简体   繁体   English

想象一下PHP中的PNG压缩

[英]Imagick PNG compression in PHP

I have been scouring stackoverflow as well as PHP / Imagick documentation in order to get this to work. 我一直在搜索stackoverflow以及PHP / Imagick文档,以使其工作。 I have PNG images stored on my server, which are then returned to my iOS app. 我的PNG图像存储在我的服务器上,然后返回到我的iOS应用程序。 I need to return them as resized and cropped images, so I am using Imagick. 我需要将它们作为调整大小和裁剪的图像返回,所以我使用的是Imagick。 Thus, so far I have: 因此,到目前为止,我有:

$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;

For setImageCompression, I have tried every single compression constant listed here: http://php.net/manual/en/imagick.constants.php , as there is no specific one for PNGs, but none of them seem to change the file size. 对于setImageCompression,我已经尝试了这里列出的每个压缩常量: http//php.net/manual/en/imagick.constants.php ,因为没有特定的PNG,但它们似乎都没有改变文件大小。 (Is there a particular one supposed to be used for PNGs?) I have also changed the value in setImagesCompressionQuality around, but none of these changes seem to make any difference either. (是否有一个特定的用于PNG?)我也改变了setImagesCompressionQuality中的值,但这些变化似乎也没有任何区别。 I've seen that some people were never able to get Imagick to work, while others were, and was hoping for a more updated answer. 我已经看到有些人从来没有能够让Imagick工作,而其他人则是,并希望得到更新的答案。 Any help appreciated! 任何帮助赞赏!

It is the function setImageCompressionQuality to set the compression level that is done for PNG images. 函数setImageCompressionQuality用于设置为PNG图像完成的压缩级别。 As PNG is a lossless image format, this does not affect the actual image quality (like it does for JPEG images) instead it just tells the library how much effort, and which strategy to use when compressing the images. 由于PNG是一种无损图像格式,因此不会影响实际图像质量(就像它对JPEG图像一样),而只是告诉图书馆在压缩图像时需要多少努力以及使用哪种策略。 The code below runs through all of the possible options. 下面的代码贯穿所有可能的选项。

I also tried pngcrush with the command line: pngcrush -brute Original.png pngcrushBrute.png to see how much more space could be saved. 我也试过pngcrush使用命令行: pngcrush -brute Original.png pngcrushBrute.png看到更多的空间如何才能得救。

  • Original.png: 192,382 bytes - Without setting any specific compression level Original.png:192,382字节 - 不设置任何特定的压缩级别
  • FullColor92.png: 181,832 bytes - the best output from all the possible options. FullColor92.png:181,832字节 - 所有可能选项的最佳输出。
  • pngcrushBrute.png: 178,129 bytes - which is probably more due to removing extra headers than that much better compression. pngcrushBrute.png:178,129字节 - 这可能更多是由于删除额外的标头而不是更好的压缩。

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

Original.jpg: 27,626 bytes \\o/ Original.jpg:27,626字节\\ o /

To summarise: 总结一下:

  • Imagick/ImageMagick already gets close to the best compression with the default settings. Imagick / ImageMagick已经接近使用默认设置的最佳压缩。
  • If you need to get the best compression, then using PngCrush will give a slightly better result than Imagick can. 如果你需要获得最好的压缩,那么使用PngCrush会比Imagick提供更好的结果。
  • If the image is a photo, serve it as a jpg. 如果图像是照片,请将其作为jpg使用。 It it's a diagram/must be served with a png, you could try color reduction, which would give good 'compression' but isn't suitable for photos, as it looks crap. 它是一个图表/必须与png一起提供,你可以尝试减少颜色,这将提供良好的“压缩”,但不适合照片,因为它看起来很糟糕。

The code used: 使用的代码:

//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";
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM