[wp-trac] [WordPress Trac] #63448: Image quality significantly degrades for resized PNGs with transparency in WordPress 6.8.1
WordPress Trac
noreply at wordpress.org
Fri May 23 16:43:32 UTC 2025
#63448: Image quality significantly degrades for resized PNGs with transparency in
WordPress 6.8.1
-------------------------------------------------+-------------------------
Reporter: elvismdev | Owner:
| adamsilverstein
Type: defect (bug) | Status: reopened
Priority: normal | Milestone: 6.8.2
Component: Media | Version: 6.8
Severity: critical | Resolution:
Keywords: has-patch has-test-info dev- | Focuses:
feedback has-unit-tests commit fixed-major |
-------------------------------------------------+-------------------------
Comment (by nosilver4u):
@SirLouen With `quantizeImage`, I'm getting 8-bit alpha after quantizing
thumbs for oval-or8.png, so that's one win. For the grayscale issue, I
think there are a few potential issues when doing as you said:
{{{
$this->image->quantizeImage( 257, Imagick::COLORSPACE_RGB, 0, false, false
);
}}}
First, 257 is too high, as an indexed image can only have 256 palette
entries. The SO thread is quite old, and I suspect the commenters were
fighting old bugs in IM. Using 257 colors was their attempt to prevent IM
from using indexed mode, but still keeping the number of colors down,
which improves the PNG compression dramatically--just not as much as a
properly indexed PNG.
Now, often the quantization doesn't use as many colors as you allow, so
257 will still work on some images, and not on others. Also, some folks
claim that you might need to use 255 to allow 1 entry for alpha. I could
never confirm or deny that, given `quantizeImage` frequently uses less
colors than specified, so I stuck with 255 as the max. We'd then have
this:
{{{
$this->image->quantizeImage( 255, Imagick::COLORSPACE_RGB, 0, false, false
);
}}}
Second, I think you might get better results with `getColorspace()`. At
least that's what we came up with last year, though I honestly couldn't
tell you whether I tested that for sure, or if I picked it up from some
other place online. We can supply the colorspace like this then:
{{{
$this->image->quantizeImage( 255, $this->image->getColorspace(), 0, false,
false );
}}}
Third, the number of colors in the original PNG can be far less than 255.
So for test8.png, using 255 when the original has only 9, you could get a
20x larger image than you want. Here the original core fix isn't great
since it relied on the (flaky) getImageDepth to set the maximum colors.
But it could have been sufficient, as it uses `getImageColors` and uses
that number if it is less than the maximum.
But then again, this all happens after the image has been scaled, at which
point the number of colors is far too high (50,000 or more on certain
sizes), so then $max_colors isn't constrained properly at all.
In EWWW IO, we run `getImageColors` to get the current color count prior
to scaling, and then constrain that similarly by the number of colors
allowed for the bit depth: 8-bit=255 colors, 4-bit=16 colors, 2-bit=4
colors, 1-bit=2 colors. *255 instead of 256 due to the aforementioned
possibility that alpha takes up 1 entry. I checked again back to Ubuntu
16, and `getImageColors` appears to work properly even on ancient versions
of IM. So we can do something like this:
{{{
$max_colors = $max_colors = pow( 2, $indexed_pixel_depth ); // or use a
switch/case statement...
if ( is_callable( array( $this->image, 'getImageColors' ) ) ) {
$current_colors = $this->image->getImageColors();
$max_colors = min( $max_colors, $current_colors );
}
// do the scaling/resizing, and afterward...
$this->image->quantizeImage( $max_colors, $this->image->getColorspace(),
0, false, false );
}}}
As for the grayscale issue, once the above is done, this seems to work for
me:
{{{
if ( Imagick::COLORSPACE_GRAY === $this->image->getImageColorspace() ) {
$this->image->setOption( 'png:format', 'png8' );
}
}}}
I added some debugging into our code in EWWW IO, and it's definitely
detecting `Imagick::COLORSPACE_GRAY`. If you're still not getting that,
I'd be curious what version of IM you've got. My dev server with Ubuntu
24.04 is running IM 6.9.12-98 and seems to work. For reference, this is
what I'm working with in EWWW IO after updating our code to use
`getImageProperty()`: https://github.com/nosilver4u/ewww-image-
optimizer/blob/ed85dd1de2c49bdfc690e1924737e626e4fc0c17/classes/class-
ewwwio-imagick-editor.php#L350
--
Ticket URL: <https://core.trac.wordpress.org/ticket/63448#comment:63>
WordPress Trac <https://core.trac.wordpress.org/>
WordPress publishing platform
More information about the wp-trac
mailing list