PHP中的Imagick PNG压缩

use*_*236 5 php compression imagick

我一直在搜索 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;
Run Code Online (Sandbox Code Playgroud)

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. (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. 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. Any help appreciated!

Dan*_*ack 0

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

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

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

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

Original.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";
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 由于某种原因,这给了我 101 个完全相同的文件,看起来它实际上并没有压缩任何东西:/ (4认同)