Imagick PHP中的PNG压缩

5

我一直在浏览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工作,而有些人则可以,希望得到更更新的答案。感谢任何帮助!

这个有帮助吗:http://www.imagemagick.org/discourse-server/viewtopic.php?t=24134 - Danack
@Danack 我已经尝试使用各种压缩质量 - 似乎根本不会改变文件大小。 - user3781236
1个回答

0

这是函数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";
    }
}

1
我还会添加 $output->stripImage(); - Jabari
4
出于某些原因,这使我得到了101个完全相同的文件,似乎它并没有真正压缩任何内容 :/ - Brian Leishman
我也是,但是文件的100个副本比原始文件更大(一个“原始”的png屏幕截图)。 - ashleedawg
@ashleedawg 可能图片已经被优化了...但也可能是一个 bug。请尝试使用 pngcrush 或在线 png 优化工具。如果这些工具可以更好地压缩 png,请在 https://github.com/imagick/imagick 上提交一个问题,我会仔细看一下。 - Danack
在 GitHub 上更新的答案 https://github.com/ImageMagick/ImageMagick/issues/29 使用 setCompressionQuality() 而不是 setImageCompressionQuality() - vee

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