【问题标题】:PHP Imagick JPEG OptimizationPHP Imagick JPEG 优化
【发布时间】:2015-05-24 03:22:53
【问题描述】:

我正在使用PHP Imagick 在运行时调整图像大小。该网站有图片上传功能,我们不能相信用户使用网络友好的JPEGs,因为在mass-import 期间有很多35MB 的图片,甚至还有一些和@ 一样大987654326@。每个图像都会变成一个缩略图 (200x200),当从列表视图进入详细视图时,只显示一个图像,所以性能并不是什么大问题,尽管我们不能完全把它扔到一边。以下是我们目前正在做的事情:

$iMagick = new Imagick($file);
$iMagick->setImageResolution(72,72);
$iMagick->resampleImage(72,72,imagick::FILTER_UNDEFINED,1);
$geometry = $iMagick->getImageGeometry();
if ($geometry['height'] > 1920 || $geometry['width'] > 1080) {
    $iMagick->scaleImage(1920, 0);
    if($geometry['height'] > $resizeHeight) {
        $iMagick->scaleImage(0, 1080);
    }
}
$iMagick->setImageCompression(Imagick::COMPRESSION_JPEG);
$iMagick->setImageCompressionQuality($compression);
$iMagick->writeImage($file);
$Imagick->clear();

旁注:我刚刚意识到我的条件逻辑中关于高度/宽度的缺陷,所以暂时忽略它。我将很快编辑问题以反映正确的条件比较。对于那些没有捕捉到它的人,它会将所有图像缩放到 1920 宽,即使它应该缩放高度,然后在缩放后将其大小缩小到 1080 height

我用来测试的图像以3MB 2398×2400 图像开头。将其缩放到1079x1080 会生成1.5MB 图像,然后以70 的质量添加JPEG 压缩会将其缩小到750KB。使用 kraken.io 可以将图像压缩到 60KB 以下。由于该脚本需要在运行时优化图像,因此我可以对它做些什么额外的事情?

我已经阅读了使用 libjpeg 的建议,它已安装,但我找不到任何文档说明它启用了哪些功能,或者是否有办法强制 Imagick 专门使用它。我什至不确定 Imagick 是否已经在使用它。

编辑:解决方案

function itm_optimizeImage($file, $compression = 70, $maxDimensions = ['width' => null, 'height' => null]) {
    $save = false;
    $fi = new finfo(FILEINFO_MIME);
    $mime = explode(';', $fi->file($file));
    switch ($mime[0]) {
        // possible to optimize other image types in the future
        case 'image/jpeg':
            try {
                $iMagick = new Imagick($file);
                if ($iMagick->getImageCompressionQuality() > $compression) {
                    $file = !itm_compressJPEG($file, $compression, $maxDimensions, $iMagick);
                }
            }
            catch (Exception $e) {
                error_log(__FUNCTION__ . " $path/$file failed: " . $e->getMessage());
                return false;
            }
            if ($file) {
                $pathParts = pathinfo($file);
                rename($file, $pathParts['dirname'] . '/' . $pathParts['filename'] . '.large.' . $pathParts['extension']);
                $iMagick->writeImage($file);
            }
            $iMagick->clear();
            break;
    }

    return $file;
}

function itm_compressJPEG($file, $compression = 70, $maxDimensions = ['width' => null, 'height' => null], &$iMagick = null) {
    try {
        $iMagickCreated = true;
        if ($iMagick) $iMagickCreated = false;
        else $iMagick = new Imagick($file);

        $iMagick->setImageResolution(72,72);
        $iMagick->resampleImage(72,72,imagick::FILTER_UNDEFINED,1);
        $geometry = $iMagick->getImageGeometry();
        if (($geometry['width'] / $maxDimensions['width']) > ($geometry['height'] / $maxDimensions['height'])) {
            // scale by width
            $iMagick->scaleImage($maxDimensions['width'], 0);
        } else {
            // scale by height
            $iMagick->scaleImage(0, $maxDimensions['height']);
        }
        $iMagick->setImageCompression(Imagick::COMPRESSION_JPEG);
        $iMagick->setImageCompressionQuality($compression);
        $iMagick->setImageFormat('jpg');
        $iMagick->stripImage();

        if ($iMagickCreated) {
            $pathParts = pathinfo($file);
            rename($file, $pathParts['dirname'] . '/' . $pathParts['filename'] . '.large.' . $pathParts['extension']);
            $iMagick->writeImage($file);
            $Imagick->clear();
        }
        return $file;
    }
    catch (Exception $e) {
        error_log(__FUNCTION__ . " $path/$file failed: " . $e->getMessage());
        return false;
    }
}

【问题讨论】:

  • 60KB 的 1079x1080 图像看起来相当不错。我认为如果不降低像素尺寸或严重降低质量,您无法将其缩小很多。
  • 问题是我的脚本并没有接近它。现在大约 750KB,60KB 是一个比较(kraken.io 工具在同一张图像上的能力)。我没有将 60KB 视为一个确切的目标,但小于 200KB 会很好。

标签: php jpeg imagick libjpeg image-compression


【解决方案1】:

将 setImageCompressionQuality 设置为 70 并在其后添加这两行。

$image->setImageFormat("jpg");
$image->stripImage();

这将大大减小图像的大小。

【讨论】:

  • 我之前用过stripImage(),没有效果。添加不带 stripImage() 的 setImageFormat('jpg') 将大小减少了约 20KB(我们试图保存 exif/meta 数据,但它对性能来说是次要的)。将两者结合使用,这张测试图像的最终结果是 178KB,这是质量和压缩的完美结合。谢谢!
  • 有人对@MaKR 描述的奇怪行为有解释吗?如果文件名以 .jpg 结尾,为什么还需要 setImageFormat('jpg')?为什么首先需要 setImageCompression() ?所有这些 Imagick 废话都有解释吗?
  • 优秀的解决方案...我仅将 5MB 的图像压缩到 788KB,通过这些额外的方法,文件大小达到两位数 KB。
  • 这仍然很好用。一切都大大减少了。样本 jpg 从 45747kb 变为 12818kb。不过必须小心。原始文件被错误地上传为PNG,文件大小膨胀到121778kb!所以,请远离 png,我猜...
猜你喜欢
  • 2011-07-24
  • 1970-01-01
  • 2018-05-28
  • 1970-01-01
  • 2015-07-23
  • 2012-12-13
  • 1970-01-01
  • 2019-01-27
  • 1970-01-01
相关资源
最近更新 更多