Сжатие Imagick PNG в PHP

2

Я пробовал 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 работать, в то время как другие были, и надеялись на более свежий ответ. Любая помощь ценится!

  • 0
    Это какая-то помощь: imagemagick.org/discourse-server/viewtopic.php?t=24134
  • 0
    @Danack Я уже пытался использовать различные качества сжатия - кажется, не меняет размер файла вообще
Теги:
compression
imagick

1 ответ

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

Original.jpg: 27,626 bytes\o/

Обобщить:

  • Imagick/ImageMagick уже приближается к лучшему сжатию с настройками по умолчанию.
  • Если вам нужно получить лучшее сжатие, то использование PngCrush даст немного лучший результат, чем Imagick.
  • Если изображение является фотографией, используйте его как jpg. Это диаграмма/должна быть подана с помощью png, вы можете попробовать уменьшить цвет, что даст хорошее "сжатие", но не подходит для фотографий, поскольку оно выглядит дерьмо.

Используемый код:

//10 digit:
//
//        0 or omitted: Use Z_HUFFMAN_ONLY strategy with the
//           zlib default compression level
//
//        1-9: the zlib compression level
//
//     1 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 ();
  • 1
    По какой-то причине это дало мне 101 точно такой же файл, не похоже, что он на самом деле что-то сжал: /

Ещё вопросы

Сообщество Overcoder
Наверх
Меню