Imagick / imagick

🌈 The Imagick PHP extension 🌈
http://pecl.php.net/imagick
Other
536 stars 135 forks source link

setImageCompressionQuality isn't doing anything for PNGs #176

Open andrews05 opened 8 years ago

andrews05 commented 8 years ago

I'm using Imagick 3.4.1 with ImageMagick 6.9.5-3 (built with mozjpeg). I load a png image in Imagick, fiddle with setImageCompressionQuality and then write it out again but no matter what I set the quality to, the filesize doesn't change. If I run ImageMagick convert on the same file, the quality setting works fine. Any idea why this would be? Are there some other options I need to set?

filex commented 8 years ago

I can confirm the problem with this code (with PHP7, Imagick 3.4.3RC1, ImageMagick 7.0.2):

$i = new Imagick('lenna.png');
$i->setImageFormat("png");
$i->setImageCompressionQuality(5);
$i->writeImage("out05.png");

All quality values (0-99) produce a 474630 byte file. PNG q=5 should skip the zlib compression step, which should produce a much larger file.

Using convert results in different output sizes:

$ convert lenna.png -quality 5 out05c.png
$ ls -l out05c.png
.. 754255 bytes ..

However, using the other quality setter method works for me:

$i = new Imagick('lenna.png');
$i->setImageFormat("png");
$i->setCompressionQuality(5);
$i->writeImage("out05.png");

Now, the q5 png is 754255 bytes. As the q default (in ImageMagick) is 75, q=75 results in the already seen 474630 bytes file.

The ImageMagick png coder reads the quality from the image_info struct, which can be altered with MagickSetCompressionQuality() (from Imagick::setCompressionQuality()).

Interestingly, this method is not able to set the quality for other image (output) formats such as JPG. Here, q=5 should produce a small file, but it doesn't:

::setCompressionQuality(5) -> 110746 bytes
::setImageCompressionQuality(5) -> 3229 bytes

The ImageMagick JPG coder reads the quality directly from the Image struct (although the image_info is also present). convert works as aspected with jpg output, too. Somehow, convert manages to set the quality in both places.

andrews05 commented 8 years ago

Thanks for investigating this, and thanks for pointing out the alternative! Happy to use that instead.

LIXiangChen commented 5 years ago

setImageCompressionQuality() is not work at all, length of the generated files are totally same, only a few bytes are different.

But I found an effective way, that is use setOption('png:compression-level', 9), the value range is 0-9.

Danack commented 5 years ago

Hi @LIXiangChen ,

I made some test with image compression in a previous thread here:

https://github.com/ImageMagick/ImageMagick/issues/29#issuecomment-143263506

Apparently it is $image->setCompressionQuality() that should be used for png images.

LIXiangChen commented 5 years ago

Hi @Danack ,

Yes, I saw that post. Even though setCompressionQuality() is available, the unavailability of setImageCompressionQuality() is still doesn't make sense. I tend to think that this is a bug. Use setOption() is also good, at least it command is very clear.

cmb69 commented 5 years ago

Did you try something like:

$image->setImageCompression(Imagick::COMPRESSION_ZIP);
$image->setImageCompressionQuality(5);

(basically taken from user comments on http://php.net/manual/en/imagick.setimagecompressionquality.php)

cmb69 commented 3 years ago

FTR, this issue had also reported as https://bugs.php.net/77127 which I've now closed as duplicate.

Regarding the issue at hand: Imagick::setImageCompressionQuality() is a thin wrapper over MagickSetImageCompressionQuality(), and the quality parameter is clearly documented as

the image compression tlityype.

That says it all. ;)