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