duanlu0559 2014-04-29 16:54
浏览 52
已采纳

Imagemagick - 包含裁剪中的图像

I don't use Imagemagick very often, which is why I don't know how to solve this problem. I also don't know how to phrase the question other than: How do I get the image to be cropped like the CSS property: background-size: contain; I haven't been able to find an answer, likely due to my phrasing.

I need the image to be 200px, and "resized/cropped" so that it is not stretched, but contained by the width or height (dependent on the orientation of the image width > height = contain by width)

What I have so far:

$im = new Imagick($path);

/* Resizing Operations */

$gm = $im->getImageGeometry();
$w = $gm['width'];
$h = $gm['height'];

if($h < $w) {
    $nh = 200;
    $nw = (200 / $h) * $w;
} else {
    $nw = 200;
    $nh = (200 / $w) * $h;
}

$im->resizeImage($nw, $nh, Imagick::FILTER_LANCZOS, true);
$im->cropThumbnailImage(200,200);

/* End Resizing Operations */

Which produces an image with the center chopped out.

Here's a visual example

We have this logo:

Original Logo


And then we want it to be constrained to 200px wide and 200px high, contained:

resized

Essentially like setting the canvas height, while not adjusting the image height.

  • 写回答

2条回答 默认 最新

  • douchigu1723 2014-04-29 18:25
    关注

    Came up with this algorithm based on the extent method of ImageMagick, which achieves the same result as CSS's background-size: contain;

    You can set the 200 value in the resizeImage function to get your end product. Works beautifully!

    $im = new Imagick($path);
    
    /* Resizing Operations */
    $gm = $im->getImageGeometry();
    $w = $gm['width'];
    $h = $gm['height'];
    
    if($h < $w) {
        $sr = $w;
        $horz = TRUE;
    } else if($h > $w) {
        $sr = $h;
        $horz = FALSE;
    } else {
        $square = TRUE;
    }
    
    if(!$square && $horz) {
        $srs = $sr / 2;
        $extent_amt = $srs - ($h / 2);
        $im->extentImage($sr, $sr, 0, 0 - $extent_amt);
    } else if(!$square && !$horz) {
        $srs = $sr / 2;
        $extent_amt = $srs - ($w / 2);
        $im->extentImage($sr, $sr, 0 - $extent_amt, 0);
    }
    
    $im->resizeImage(200, 200, Imagick::FILTER_LANCZOS, true);
    
    /* End Resizing Operations */
    
    $im->writeImage($path);
    
    /* Clean up time */
    $im->clear();
    $im->destroy();
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 求差集那个函数有问题,有无佬可以解决
  • ¥15 【提问】基于Invest的水源涵养
  • ¥20 微信网友居然可以通过vx号找到我绑的手机号
  • ¥15 寻一个支付宝扫码远程授权登录的软件助手app
  • ¥15 解riccati方程组
  • ¥15 display:none;样式在嵌套结构中的已设置了display样式的元素上不起作用?
  • ¥15 使用rabbitMQ 消息队列作为url源进行多线程爬取时,总有几个url没有处理的问题。
  • ¥15 Ubuntu在安装序列比对软件STAR时出现报错如何解决
  • ¥50 树莓派安卓APK系统签名
  • ¥65 汇编语言除法溢出问题