Skip to content

Commit 4be91f3

Browse files
committed
Fix: Apply PNG quantization only to true indexed images with ≤ max colors
This refines the logic introduced in [59589] to prevent image quality degradation on resized PNGs. Quantization is now only applied when: - The image is indexed (color-type-orig == 3) - The actual color count (getImageColors) is ≤ the max allowed by bit depth This preserves the original optimization goals (palette size reduction) while preventing unintended degradation on full-color or gradient-rich images. Also maintains grayscale (png8) support and alpha channel chunk handling. Props @SirLouen @siliconforks @wildworks Fixes #63448
1 parent f6ed800 commit 4be91f3

File tree

1 file changed

+10
-9
lines changed

1 file changed

+10
-9
lines changed

src/wp-includes/class-wp-image-editor-imagick.php

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -485,32 +485,33 @@ protected function thumbnail_image( $dst_w, $dst_h, $filter_name = 'FILTER_TRIAN
485485
$this->image->setOption( 'png:compression-level', '9' );
486486
$this->image->setOption( 'png:compression-strategy', '1' );
487487

488-
// Check for an alpha channel.
488+
// Handle alpha chunk inclusion or exclusion.
489489
if (
490-
is_callable( array( $this->image, 'getImageAlphaChannel' ) )
491-
&& $this->image->getImageAlphaChannel()
490+
is_callable( array( $this->image, 'getImageAlphaChannel' ) ) &&
491+
$this->image->getImageAlphaChannel()
492492
) {
493493
$this->image->setOption( 'png:include-chunk', 'tRNS' );
494494
} else {
495495
$this->image->setOption( 'png:exclude-chunk', 'all' );
496496
}
497497

498-
// Reduce colors in the image only if it's an indexed PNG with <= 256 colors.
498+
// Only apply quantization to actual indexed PNGs.
499499
if (
500500
is_callable( array( $this->image, 'getImageColors' ) ) &&
501+
is_callable( array( $this->image, 'getImageDepth' ) ) &&
501502
is_callable( array( $this->image, 'getImageProperty' ) )
502503
) {
503504
$current_colors = $this->image->getImageColors();
504-
$color_type = $this->image->getImageProperty( 'png:IHDR.color_type' );
505+
$bit_depth = $this->image->getImageDepth();
506+
$max_colors = pow( 2, $bit_depth );
507+
$color_type = $this->image->getImageProperty( 'png:IHDR.color-type-orig' );
505508

506-
if ( $current_colors <= 256 && '3' === $color_type ) {
509+
if ( $current_colors <= $max_colors && '3' === $color_type ) {
507510
$this->image->quantizeImage( $current_colors, $this->image->getColorspace(), 0, false, false );
508511
}
509512
}
510513

511-
/**
512-
* If the colorspace is 'gray', use the png8 format to ensure it stays indexed.
513-
*/
514+
// If grayscale, ensure format is png8 to retain index palette.
514515
if ( Imagick::COLORSPACE_GRAY === $this->image->getImageColorspace() ) {
515516
$this->image->setOption( 'png:format', 'png8' );
516517
}

0 commit comments

Comments
 (0)