【问题标题】:Imagick PNG compression in PHPPHP中的Imagick PNG压缩
【发布时间】:2019-09-13 14:43:28
【问题描述】:

我一直在搜索 stackoverflow 以及 PHP / Imagick 文档以使其正常工作。我在我的服务器上存储了 PNG 图像,然后将其返回到我的 iOS 应用程序。我需要将它们作为调整大小和裁剪的图像返回,所以我使用的是 Imagick。因此,到目前为止,我有:

$image_name = $_POST['filepath'];
if(!file_exists($image_name)){ return ""; }
header("Content-Type: image/png");

$image = new Imagick($image_name);
$image->resizeImage($_POST['width'], $_POST['height'], Imagick::FILTER_LANCZOS, 1);
$image->roundCorners($_POST['width'], $_POST['height']);
$image->setImageFormat("png");
$image->setImageCompression(\Imagick::COMPRESSION_UNDEFINED);
$image->setImageCompressionQuality(0);
$image->stripImage();
echo $image;

对于 setImageCompression,我已经尝试了此处列出的每个压缩常量:http://php.net/manual/en/imagick.constants.php,因为没有针对 PNG 的特定压缩常量,但它们似乎都不会改变文件大小。 (是否有一个特定的用于 PNG 的?)我还更改了 setImagesCompressionQuality 中的值,但这些更改似乎也没有任何区别。我看到有些人永远无法让 Imagick 工作,而另一些人则希望得到更新的答案。任何帮助表示赞赏!

【问题讨论】:

标签: php compression imagick


【解决方案1】:

函数setImageCompressionQuality 用于设置PNG 图像的压缩级别。由于 PNG 是一种无损图像格式,因此这不会影响实际的图像质量(就像对 JPEG 图像所做的那样),它只是告诉库需要多少努力,以及在压缩图像时使用哪种策略。下面的代码遍历所有可能的选项。

我还尝试了pngcrush 与命令行:pngcrush -brute Original.png pngcrushBrute.png,看看可以节省多少空间。

  • Original.png:192,382 字节 - 未设置任何特定压缩级别
  • FullColor92.png:181,832 字节 - 所有可能选项的最佳输出。
  • pngcrushBrute.png:178,129 字节 - 这可能更多是由于删除了额外的标头而不是更好的压缩。

    $imagick->setImageFormat('jpg'); $imagick->setImageCompressionQuality(80);

原始.jpg:27,626 字节 \o/

总结一下:

  • Imagick/ImageMagick 在默认设置下已经接近最佳压缩率。
  • 如果您需要获得最佳压缩效果,那么使用 PngCrush 将提供比 Imagick 稍好的结果。
  • 如果图片是照片,请将其作为 jpg 格式提供。它是一个图表/必须与 png 一起提供,您可以尝试减少颜色,这将提供良好的“压缩”,但不适合照片,因为它看起来很垃圾。

使用的代码:

//10's digit:
//
//        0 or omitted: Use Z_HUFFMAN_ONLY strategy with the
//           zlib default compression level
//
//        1-9: the zlib compression level
//
//     1's digit:
//
//        0-4: the PNG filter method
//
//        5:   libpng adaptive filtering if compression level > 5
//             libpng filter type "none" if compression level <= 5
//or if image is grayscale or palette
//
//        6:   libpng adaptive filtering
//
//        7:   "LOCO" filtering (intrapixel differing) if writing
//a MNG, otherwise "none".  Did not work in IM-6.7.0-9
//and earlier because of a missing "else".
//
//8:   Z_RLE strategy (or Z_HUFFMAN_ONLY if quality < 10), adaptive
//             filtering. Unused prior to IM-6.7.0-10, was same as 6
//
//        9:   Z_RLE strategy (or Z_HUFFMAN_ONLY if quality < 10), no PNG filters
//             Unused prior to IM-6.7.0-10, was same as 6

$imagick = new Imagick("./Biter_500.jpg");

$imagick->setImageFormat('png');

$imagick->writeimage("./output/original.png");
compressAllTypes($imagick, "./output/FullColor");


function compressAllTypes(Imagick $imagick, $filename) {
    for ($compression = 0; $compression <= 9; $compression++) {
        echo "Compression $compression \n";
        for ($filter = 0; $filter <= 9; $filter++) {
            echo "Filter $filter";
            $output = clone $imagick;
            $output->setImageFormat('png');
            //$output->setOption('png:format', 'png8');
            $compressionType = intval($compression . $filter);
            $output->setImageCompressionQuality($compressionType);
            $outputName = $filename."$compression$filter.png";
            $output->writeImage($outputName);
        }
        echo "\n";
    }
}

【讨论】:

  • 我还要添加 $output->stripImage();
  • 由于某种原因,这给了我 101 个完全相同的文件,看起来它实际上并没有压缩任何东西:/
  • 我也是 - 除了文件的 100 个副本比原始文件大(“原始”png 屏幕截图)。
  • @ashleedawg 图像可能已经优化......但也可能是一个错误。请您尝试使用 pngcrush 或在线 png 优化器。如果这些压缩png更好,请您在github.com/imagick/imagick打开一个问题,我会好好看看它。
  • GitHub 上的更新答案github.com/ImageMagick/ImageMagick/issues/29 使用setCompressionQuality() NOT setImageCompressionQuality()
猜你喜欢
  • 2011-11-19
  • 2012-01-17
  • 2014-01-10
  • 2010-12-29
  • 2013-03-24
  • 1970-01-01
  • 2012-04-14
  • 1970-01-01
  • 2011-10-18
相关资源
最近更新 更多