简体   繁体   English

有没有办法使用JCrop裁剪比实际图像更大的区域?

[英]Is there a way to use JCrop to crop an area larger than the actual image?

From what I can tell, JCrop will not let me set things up so the user can crop outside the actual image and include surrounding whitespace. 据我所知, JCrop不会让我进行设置,因此用户可以在实际图像之外裁剪并包含周围的空白。 Is there a way to do that? 有没有办法做到这一点?

To help explain what I mean, say we are restricting our crop to a 16:9 ratio. 为了帮助解释我的意思,我们说我们将我们的作物限制在16:9的比例。 That works fine for an image with a naturally wide subject: 这适用于具有自然宽广主题的图像:

在此输入图像描述

But sometimes the source image that a user wants to use does not comfortably accommodate the desired ratio: 但有时用户想要使用的源图像并不能轻松适应所需的比例:

在此输入图像描述

Instead, we'd like to allow them to include space outside the image by making the crop area larger than the image itself: 相反,我们希望通过使裁剪区域大于图像本身来允许它们在图像外部包含空间:

在此输入图像描述

I've been messing around with JCrop and looking through the manual and Google for a while and it doesn't look like this is possible (without modifying JCrop). 我一直在搞乱JCrop并查看手册和谷歌一段时间,看起来这不可能(不修改JCrop)。 Am I wrong? 我错了吗? If so, how do you do it? 如果是这样,你怎么做?

FWIW, the actual images in this case will be product/organization logo images, which come in a large variety of aspect ratios, and almost always the images available to people have almost no whitespace around the text/imagery. FWIW,在这种情况下的实际图像将是产品/组织徽标图像,其具有多种宽高比,并且几乎总是人们可用的图像在文本/图像周围几乎没有空白。 Which means any fixed aspect ratio crop restricted to the bounds of the image will almost certainly chop off either the top+bottom or left+right sides of the image. 这意味着限制在图像边界的任何固定宽高比裁剪几乎肯定会切断图像的顶部+底部或左侧+右侧。

My solution was to create a temporary canvas with square dimensions equal to the largest side of the image. 我的解决方案是创建一个方形尺寸等于图像最大边的临时画布。 I made the canvas background white and added the image in the center. 我将画布背景设为白色并在中心添加了图像。 Then I created a new image and used the canvas as the image source. 然后我创建了一个新图像并使用画布作为图像源。 Then I used that image with jcrop. 然后我用jcrop使用了那个图像。 It's slower, but it works! 它的速度较慢,但​​确实有效!

Here's an example: 这是一个例子:

img.onload = function(){ 
    // get the largest side of the image
    // and set the x and y coordinates for where the image will go in the canvas
    if( img.width > img.height ){
        var largestDim = img.width;
        var x = 0;
        var y = (img.width-img.height)/2;
    }
    else{
        var largestDim = img.height;
        var y = 0;
        var x = (img.height-img.width)/2;
    }
    // create a temporary canvas element and set its height and width to largestDim
    canvastemp = document.createElement("canvas");
    canvastemp.width = canvastemp.height = largestDim;
    var ctx = canvastemp.getContext('2d');
    // set the canvas background to white
    ctx.fillStyle="#FFFFFF";
    ctx.fillRect(0, 0, canvastemp.width, canvastemp.height);
    // center the image in the canvas
    ctx.drawImage(img, x, y, img.width, img.height);
    // create a new image and use the canvas as its source
    var squaredImg = document.createElement("img");
    squaredImg.src = canvastemp.toDataURL();
    // add jcrop once the image loads
    squaredImg.onload = function(){
        addJcrop(squaredImg);   
    }
};

function addJcrop(img){
   // your jcrop code
}

This way users can choose to include the entire image in the crop if they wish. 这样,用户可以根据需要选择将整个图像包含在裁剪中。

考虑使用像php imagick这样的东西将照片转换为照片+透明的大背景,然后把它放到JCrop我不认为它可能的其他方式

You could fool the jCrop script. 你可以欺骗jCrop脚本。 Instead of showing image.jpg , you do something like not_a_real_image.php?imagename=image.jpg . 而不是显示的image.jpg ,你这样做not_a_real_image.php?imagename=image.jpg Then give the php file a header of the image, and a width and height, and align the actual image in the center of that. 然后给php文件一个图像的标题,宽度和高度,并将实际图像对齐。

All you have to do is remember the amount of canvas you've added to correct it later on. 您所要做的就是记住您之后添加的用于更正的画布数量。

I made a function using Imagick: 我用Imagick做了一个函数:

function resizeImage($imgSrc, $width, $height, $createBg, $output, $show) {

    $img = new Imagick($imgSrc);

    if ($img->getImageWidth() / $img->getImageHeight() < $width / $height) {
        $img->thumbnailImage(0, $height);
    } else {
        $img->thumbnailImage($width, 0);
    }

    $canvas = new Imagick();
    $canvas->newImage($width, $height, 'white', 'jpg');

    /* Creates a background image (good for vertical images in horizontal canvas or vice-versa) */
    if ($createBg) {

        $imgBg = new Imagick($imgSrc);

        if ($imgBg->getImageWidth() / $imgBg->getImageHeight() < $width / $height) {
            $imgBg->thumbnailImage($width, 0);
        } else {
            $imgBg->thumbnailImage(0, $height);
        }

        $imgBg->blurImage(0, 80);

        $geometryBg = $imgBg->getImageGeometry();
        $xBg = ( $width - $geometryBg['width'] ) / 2;
        $yBg = ( $height - $geometryBg['height'] ) / 2;

        $canvas->compositeImage( $imgBg, imagick::COMPOSITE_OVER, $xBg, $yBg );
    }

    /* Center image */
    $geometry = $img->getImageGeometry();
    $x = ( $width - $geometry['width'] ) / 2;
    $y = ( $height - $geometry['height'] ) / 2;

    $canvas->compositeImage( $img, imagick::COMPOSITE_OVER, $x, $y );

    /* Save image  */
    if ($output) {
        $canvas->writeImage($output);
    }

    /* Show the image */
    if ($show) {
        header( 'Content-Type: image/jpg' );
        echo $canvas;
    }

}

The comment's explain it all, enjoy! 评论解释一切,享受!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM