Media: improve Imagick handling of colors and alpha channel for PNG image uploads.

Fix an issue where index color (8 bit) PNG uploads were output as true color (24 bit) PNGs, significantly increasing their size.  When using Imagick, PNG output images will now match the colors of the uploaded image.

Also, correct handling of PNG alpha channel information so it is preserved in output images.

Props adamsilverstein, pbearne, nosilver4u, peterdavehello, joemcgill, azaozz, codex-m, kirasong, justlevine, jokanane, sallyruchman, wpfed, tgsrvrs, antpb, tb1909.
Fixes #36477.


Built from https://develop.svn.wordpress.org/trunk@59589


git-svn-id: http://core.svn.wordpress.org/trunk@58975 1a063a9b-81f0-0310-95a4-ce76da25c4cd
This commit is contained in:
Adam Silverstein
2025-01-07 22:35:23 +00:00
parent 065f1ef453
commit 69b48e2e80
2 changed files with 33 additions and 2 deletions

View File

@@ -484,7 +484,38 @@ 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' );
$this->image->setOption( 'png:exclude-chunk', 'all' );
// 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' );
}
}
}
}
/*

View File

@@ -16,7 +16,7 @@
*
* @global string $wp_version
*/
$wp_version = '6.8-alpha-59588';
$wp_version = '6.8-alpha-59589';
/**
* Holds the WordPress DB revision, increments when changes are made to the WordPress DB schema.