如何在PHP中使用Imagick?(调整大小和裁剪)

17

我使用imagick进行缩略图裁剪,但有时裁剪后的缩略图会丢失图片的顶部部分(头发、眼睛)。

我考虑先调整图像大小再进行裁剪。此外,我需要保持图像大小比例不变。

以下是我用于裁剪的php脚本:

$im = new imagick( "img/20130815233205-8.jpg" );
$im->cropThumbnailImage( 80, 80 );
$im->writeImage( "thumb/th_80x80_test.jpg" );
echo '<img src="thumb/th_80x80_test.jpg">';

谢谢..


你遇到了什么错误?期望的输出是什么?使用的是哪个版本的PHP?是否安装了imagick?请提供更多细节... - Elias Van Ootegem
1
不,这不是关于错误的问题。imagick工作正常。上面的脚本只进行了裁剪。我想先调整大小,然后再裁剪它,所以我错过了第一步... - newworroo
首先调用 imageResize,然后... - Elias Van Ootegem
3个回答

36

这项任务并不容易,因为“重要”的部分可能并不总是出现在同一位置。但是,可以使用这样的方法。

$im = new imagick("c:\\temp\\523764_169105429888246_1540489537_n.jpg");
$imageprops = $im->getImageGeometry();
$width = $imageprops['width'];
$height = $imageprops['height'];
if($width > $height){
    $newHeight = 80;
    $newWidth = (80 / $height) * $width;
}else{
    $newWidth = 80;
    $newHeight = (80 / $width) * $height;
}
$im->resizeImage($newWidth,$newHeight, imagick::FILTER_LANCZOS, 0.9, true);
$im->cropImage (80,80,0,0);
$im->writeImage( "D:\\xampp\\htdocs\\th_80x80_test.jpg" );
echo '<img src="th_80x80_test.jpg">';

应该能够工作。cropImage参数(0和0)确定了裁剪区域的左上角位置。因此,调整这些参数可以得到不同的结果,决定了图像中保留什么。


7

基于Martin的回答,我制作了一个更通用的函数,可以调整和裁剪Imagick图像以适应给定的宽度和高度(即与CSS background-size:cover声明完全相同):

/**
 * Resizes and crops $image to fit provided $width and $height.
 *
 * @param \Imagick $image
 *   Image to change.
 * @param int $width
 *   New desired width.
 * @param int $height
 *   New desired height.
 */
function image_cover(Imagick $image, $width, $height) {
  $ratio = $width / $height;

  // Original image dimensions.
  $old_width = $image->getImageWidth();
  $old_height = $image->getImageHeight();
  $old_ratio = $old_width / $old_height;

  // Determine new image dimensions to scale to.
  // Also determine cropping coordinates.
  if ($ratio > $old_ratio) {
    $new_width = $width;
    $new_height = $width / $old_width * $old_height;
    $crop_x = 0;
    $crop_y = intval(($new_height - $height) / 2);
  }
  else {
    $new_width = $height / $old_height * $old_width;
    $new_height = $height;
    $crop_x = intval(($new_width - $width) / 2);
    $crop_y = 0;
  }

  // Scale image to fit minimal of provided dimensions.
  $image->resizeImage($new_width, $new_height, imagick::FILTER_LANCZOS, 0.9, true);

  // Now crop image to exactly fit provided dimensions.
  $image->cropImage($new_width, $new_height, $crop_x, $crop_y);
}

希望这能帮助到某些人。

2
imagick::FILTER_LANCZOS should be \Imagick::FILTER_LANCZOS - Mehmet Soylu
2
最后一行 $image->cropImage($new_width, $new_height, ... 应该改为 $image->cropImage($width, $height, ... - dersimn
对我而言,使用$image->cropImage($new_width, $new_height, 0,0);可以正常工作。 - German Khokhlov

0

我的代码,请投票

// Imagick
$image = new Imagick($img);

// method 1 - resize to max width
if($type==1){
    $image->resizeImage($newWidth,0,Imagick::FILTER_LANCZOS,1);
// method 2 - resize to max height
}else if($type==2){
    $image->resizeImage(0,$newHeight,Imagick::FILTER_LANCZOS,1);
// method 1 - resize to max width or height
}else if($type==3){
    if($image->getImageHeight() <= $image->getImageWidth()){
        $image->resizeImage($newWidth,0,Imagick::FILTER_LANCZOS,1);
    }else{
        $image->resizeImage(0,$newHeight,Imagick::FILTER_LANCZOS,1);
    }
// method 4 - resize and crop to center
}else if($type==4){
    if($image->getImageHeight() <= $image->getImageWidth()){
        $image->resizeImage(0,$newheight,Imagick::FILTER_LANCZOS,1);
    }else{
        $image->resizeImage($newwidth,0,Imagick::FILTER_LANCZOS,1);
    }
    $cropWidth = $image->getImageWidth();
    $cropHeight = $image->getImageHeight();
    
    $image->cropimage(
        $newwidth,
        $newheight,
        ($cropWidth - $newwidth) / 2,
        ($cropHeight - $newheight) / 2
    );
}

$image->setImageFormat("jpeg");
$image->setImageCompression(Imagick::COMPRESSION_JPEG);
$image->writeImages($newImg, true);
$image->clear();
$image->destroy();

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