doudang4857
2015-12-22 11:41
浏览 108
已采纳

PHP Imagick - 调整大小后文本和线条不清晰/平滑

Using PHP's Imagick library I am taking an image, resizing, cropping and setting an overlay over the top. This works fine but for images that have text or thin/intricate lines the results are very jagged.

I set the quality to 90 on output so that shouldn't be the issue. Is there anything I am doing wrong during resize/crop etc?

Link can be seen below:

http://www.tiltworld.co.uk/resize.php

http://www.tiltworld.co.uk/output.jpg

As you can see the outputted image quality is very poor with the text and lines, jagged or hard to see/read.

Here is the original full size before resizing:

http://www.tiltworld.co.uk/test.jpg

My PHP code is:

step 1: set the images

$overlay = new Imagick('http://www.tiltworld.co.uk/overlay.png');
$img = new Imagick('http://www.tiltworld.co.uk/test.jpg');
$img_d = $img->getImageGeometry(); 
$img_w = $img_d['width']; 
$img_h = $img_d['height'];

step 2: resize the image

// resize
$crop_w = round(260 * 0.53);
$crop_h = round(260 * 0.53);
list($_w, $_h) = scaleProportions($crop_w, $crop_h, $img_w, $img_h);
$img->adaptiveResizeImage($_w, $_h);

step 3: crop the image

// crop
$new_d = $img->getImageGeometry(); 
$new_w = $new_d['width']; 
$new_h = $new_d['height'];
$crop_x = ($new_w - $crop_w) / 2;
$crop_y = ($new_h - $crop_h) / 2;
$img->cropImage($crop_w, $crop_h, $crop_x, $crop_y);

step 4: place the image in center

// place
$img->setImageFormat('png');
$img->setImageBackgroundColor(new ImagickPixel('white'));
$place_x = -(260 - $crop_w) / 2; 
$place_y = -(260 - $crop_h) / 2;
$img->extentImage(260, 260, $place_x, $place_y);

step 5: merge image and overlay

// merge
$img->compositeImage($overlay, imagick::COMPOSITE_ATOP, 0, 0);

step 6: output the image

// output
header("Content-Type: image/jpg");
$img->setImageFormat('jpg');
$img->setImageCompression(Imagick::COMPRESSION_JPEG);
$img->setImageCompressionQuality(90);
echo $img->getImageBlob();

(scale function used on resize)

function scaleProportions($mw, $mh, $cw, $ch)
{
    $scale = $mh / $ch; 
    $ch = $mh; 
    $cw = $cw * $scale;
    if($cw>=$mw){
        if($ch>=$mh)
        {
            return array($cw, $ch);
        }
        else 
        {
            $scale = $mw / $cw; 
            $cw = $mw; 
            $ch = $ch * $scale;
            return array($cw, $ch);
        }
    }
    else 
    {
        $scale = $mw / $cw; 
        $cw = $mw; 
        $ch = $ch * $scale;
        return array($cw, $ch);
    }
}
  • 写回答
  • 好问题 提建议
  • 关注问题
  • 收藏
  • 邀请回答

1条回答 默认 最新

  • douchen9855 2015-12-22 15:48
    已采纳

    You're using a weird resize method. Try using the one that allows you to control how the filtering is done:

    $imagick->resizeImage($width, $height, \Imagick::FILTER_LANCZOS, 1, false);

    已采纳该答案
    评论
    解决 无用
    打赏 举报

相关推荐 更多相似问题