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

14
据我所知,JCrop似乎不允许我设置裁剪范围超出实际图片并包含周围的空白区域。是否有方法可以实现这一点?
为了更好地说明我的意思,我们限制裁剪比例为16:9。 对于一个具有自然宽幅主题的图像,这很好地起作用:
但是,有时用户想要使用的源图像并不适合所需的比例:
因此,我们希望通过使裁剪区域大于图像本身来允许他们包含图像之外的空间:
我已经试过了JCrop,并且查阅了手册和谷歌一段时间,看起来似乎不可能实现这一点(无需修改JCrop)。 我错了吗? 如果是这样,请问怎么做?
对于这种情况下的实际图像,将是产品/组织标志图像,具有各种各样的纵横比,而且几乎总是可用的图像周围几乎没有任何空白。 这意味着任何受边界限制的固定纵横比裁剪都几乎肯定会切掉图像的顶部+底部或左侧+右侧。

在Gimp中甚至不能像这样裁剪,所以我认为这不是JCrop的疏忽。 <edit>不</edit> - Mr. Polywhirl
@Mr.Polywhirl,嗯,在PhotoShop和Gimp中,您可以通过增加画布大小来实现此操作。也许我应该重新措辞我的问题以包含这个概念... 嗯。但是祝你好运在Google上搜索“javascript image crop canvas”或任何类似的内容,你只会得到HTML5画布相关的结果! - jwl
@jlarson 你解决这个问题了吗?我也遇到了同样的问题和需求——用户头像都是不同的形状,但我们的软件要求是正方形裁剪。客户对此有抱怨,但我似乎找不到任何改变 jCrop 功能的方法。 - Jeremy Miller
@JeremyMiller - 不,我没有。如果我没记错的话,我最终改变了用户界面以克服这个不足。 - jwl
我希望我不必这样做。 - Jeremy Miller
4个回答

5
我的解决方案是创建一个临时画布,其正方形尺寸等于图像的最大边。我将画布背景设置为白色,并在中心添加了图像。然后我创建了一个新图像,并使用画布作为图像源。然后我将该图像与jcrop一起使用。虽然速度较慢,但它可以工作!
以下是示例:
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
}

这样,用户可以选择在剪裁时包括整个图像。


3
考虑使用像PHP Imagick这样的工具将照片转换为带有透明背景的照片,然后将其放入JCrop中。我认为没有其他方法可以实现。

是的,那也是我会这样做的方式。我认为ImageMagick可以帮忙。 - smartmeta
我想做类似于这样的事情,但不幸的是我正在使用.NET,所以对我来说没有PHP。是否有类似于.NET的东西? - Jeremy Miller
我不熟悉.NET,但你可以尝试类似于https://dev59.com/G3RB5IYBdhLWcg3w7riV的东西。 - Jacek Pietal

2
你可以愚弄 jCrop 脚本。而不是显示 image.jpg,你可以做像 not_a_real_image.php?imagename=image.jpg 这样的事情。 然后给 php 文件一个图像头,宽度和高度,并将实际图像居中对齐在其中。
你只需要记住添加到画布的数量,以便稍后进行更正。

0
我使用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;
    }

}

评论已经解释了一切,享受吧!


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接