diff options
author | Adam Silverstein <adamsilverstein@git.wordpress.org> | 2025-05-22 21:38:22 +0000 |
---|---|---|
committer | Adam Silverstein <adamsilverstein@git.wordpress.org> | 2025-05-22 21:38:22 +0000 |
commit | 97ed38471b8cc78019417d92efa28e3e1b478f0c (patch) | |
tree | 00810db9acb991cf85c2594ca4a5f2948a07ba89 /src | |
parent | 8c011572459ef6353182f444f86adf244833f902 (diff) | |
download | wordpress-97ed38471b8cc78019417d92efa28e3e1b478f0c.tar.gz wordpress-97ed38471b8cc78019417d92efa28e3e1b478f0c.zip |
Media: fix degraded handling for 24 bit PNG uploads.
Add additional logic to correctly identify indexed PNG images so output PNGs correctly match the uploaded image depth.
Fix a regression introduced in WordPress 6.8 [59589] where uploaded Truecolor PNG images (meaning > 8 bit) were mis-identified as indexed (8 bit) images, causing output images to be indexed instead of Truecolor resulting in a noticeable visual degradation.
Props elvismdev, wildworks, SirLouen, siliconforks, joemcgill, iamshashank, nosilver4u.
Fixes #63448.
git-svn-id: https://develop.svn.wordpress.org/trunk@60246 602fd350-edb4-49c9-b593-d223f7449a82
Diffstat (limited to 'src')
-rw-r--r-- | src/wp-includes/class-wp-image-editor-imagick.php | 51 |
1 files changed, 21 insertions, 30 deletions
diff --git a/src/wp-includes/class-wp-image-editor-imagick.php b/src/wp-includes/class-wp-image-editor-imagick.php index 66085ac503..2e7c7039d5 100644 --- a/src/wp-includes/class-wp-image-editor-imagick.php +++ b/src/wp-includes/class-wp-image-editor-imagick.php @@ -484,37 +484,28 @@ class WP_Image_Editor_Imagick extends WP_Image_Editor { $this->image->setOption( 'png:compression-filter', '5' ); $this->image->setOption( 'png:compression-level', '9' ); $this->image->setOption( 'png:compression-strategy', '1' ); - // Check to see if a PNG is indexed, and find the pixel depth. - if ( is_callable( array( $this->image, 'getImageDepth' ) ) ) { - $indexed_pixel_depth = $this->image->getImageDepth(); - - // Indexed PNG files get some additional handling. - if ( 0 < $indexed_pixel_depth && 8 >= $indexed_pixel_depth ) { - // Check for an alpha channel. - if ( - is_callable( array( $this->image, 'getImageAlphaChannel' ) ) - && $this->image->getImageAlphaChannel() - ) { - $this->image->setOption( 'png:include-chunk', 'tRNS' ); - } else { - $this->image->setOption( 'png:exclude-chunk', 'all' ); - } - - // Reduce colors in the images to maximum needed, using the global colorspace. - $max_colors = pow( 2, $indexed_pixel_depth ); - if ( is_callable( array( $this->image, 'getImageColors' ) ) ) { - $current_colors = $this->image->getImageColors(); - $max_colors = min( $max_colors, $current_colors ); - } - $this->image->quantizeImage( $max_colors, $this->image->getColorspace(), 0, false, false ); - - /** - * If the colorspace is 'gray', use the png8 format to ensure it stays indexed. - */ - if ( Imagick::COLORSPACE_GRAY === $this->image->getImageColorspace() ) { - $this->image->setOption( 'png:format', 'png8' ); - } + + // Indexed PNG files get some additional handling. + // See #63448 for details. + if ( + is_callable( array( $this->image, 'getImageProperty' ) ) + && '3' === $this->image->getImageProperty( 'png:IHDR.color-type-orig' ) + ) { + + // Check for an alpha channel. + if ( + is_callable( array( $this->image, 'getImageAlphaChannel' ) ) + && $this->image->getImageAlphaChannel() + ) { + $this->image->setOption( 'png:include-chunk', 'tRNS' ); + } else { + $this->image->setOption( 'png:exclude-chunk', 'all' ); } + // Set the image format to Indexed PNG. + $this->image->setOption( 'png:format', 'png8' ); + + } else { + $this->image->setOption( 'png:exclude-chunk', 'all' ); } } |