-
Notifications
You must be signed in to change notification settings - Fork 3.2k
Check images for true alpha transparency #8933
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 4 commits
4b267f1
ca58a98
a1b4641
a6a36cf
a9546c4
8f2c1b9
1f8da9f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -444,6 +444,39 @@ protected function thumbnail_image( $dst_w, $dst_h, $filter_name = 'FILTER_TRIAN | |
| } | ||
|
|
||
| try { | ||
| $is_png = false; | ||
| $is_indexed_png = false; | ||
| $is_indexed_png_with_alpha_channel = false; | ||
| $is_indexed_png_with_true_alpha_transparency = false; | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. can we add a comment here indicating the meaning of true alpha channel (vs alpha channel)
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I've added a comment which explains the purpose of all these variables (and mentions what "true alpha" means here). Does that make things clearer?
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yes, thanks. I will update the language slightly. |
||
|
|
||
| if ( 'image/png' === $this->mime_type ) { | ||
| $is_png = true; | ||
|
|
||
| if ( | ||
| is_callable( array( $this->image, 'getImageProperty' ) ) | ||
| && '3' === $this->image->getImageProperty( 'png:IHDR.color-type-orig' ) | ||
| ) { | ||
| $is_indexed_png = true; | ||
|
|
||
| if ( | ||
| is_callable( array( $this->image, 'getImageAlphaChannel' ) ) | ||
| && $this->image->getImageAlphaChannel() | ||
| ) { | ||
| $is_indexed_png_with_alpha_channel = true; | ||
|
|
||
| if ( | ||
| is_callable( array( $this->image, 'getImageChannelDepth' ) ) | ||
| && defined( 'Imagick::CHANNEL_ALPHA' ) | ||
adamsilverstein marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| ) { | ||
| $alpha_channel_depth = $this->image->getImageChannelDepth( Imagick::CHANNEL_ALPHA ); | ||
| if ( $alpha_channel_depth > 1 ) { | ||
|
||
| $is_indexed_png_with_true_alpha_transparency = true; | ||
| } | ||
| } | ||
| } | ||
| } | ||
| } | ||
|
|
||
| /* | ||
| * To be more efficient, resample large images to 5x the destination size before resizing | ||
| * whenever the output size is less that 1/3 of the original image size (1/3^2 ~= .111), | ||
|
|
@@ -480,30 +513,42 @@ protected function thumbnail_image( $dst_w, $dst_h, $filter_name = 'FILTER_TRIAN | |
| $this->image->setOption( 'jpeg:fancy-upsampling', 'off' ); | ||
| } | ||
|
|
||
| if ( 'image/png' === $this->mime_type ) { | ||
| if ( $is_png ) { | ||
| $this->image->setOption( 'png:compression-filter', '5' ); | ||
| $this->image->setOption( 'png:compression-level', '9' ); | ||
| $this->image->setOption( 'png:compression-strategy', '1' ); | ||
|
|
||
| // 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' ) | ||
| ) { | ||
| if ( $is_indexed_png ) { | ||
|
|
||
| // Check for an alpha channel. | ||
| if ( | ||
| is_callable( array( $this->image, 'getImageAlphaChannel' ) ) | ||
| && $this->image->getImageAlphaChannel() | ||
| ) { | ||
| if ( $is_indexed_png_with_alpha_channel ) { | ||
| $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' ); | ||
|
|
||
| $this->image->quantizeImage( 256, $this->image->getColorspace(), 0, false, false ); | ||
|
|
||
| /* | ||
| * If the colorspace is 'gray', use the png8 format to ensure it stays indexed. | ||
| * ImageMagick tends to save grayscale images as grayscale PNGs rather than indexed PNGs, | ||
| * even though grayscale PNGs usually have considerably larger file sizes. | ||
| * But we can force ImageMagick to save the image as an indexed PNG instead, | ||
| * by telling it to use png8 format. | ||
| * | ||
| * Note that we need to first call quantizeImage() before checking getImageColorspace(), | ||
| * because only after calling quantizeImage() will the colorspace be COLORSPACE_GRAY for grayscale images | ||
| * (and we have not found any other way to identify grayscale images). | ||
| * | ||
| * We need to avoid forcing indexed format for images with true alpha transparency, | ||
| * because ImageMagick does not support saving an image with true alpha transparency as an indexed PNG. | ||
| */ | ||
| if ( Imagick::COLORSPACE_GRAY === $this->image->getImageColorspace() && ! $is_indexed_png_with_true_alpha_transparency ) { | ||
adamsilverstein marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| // Set the image format to Indexed PNG. | ||
| $this->image->setOption( 'png:format', 'png8' ); | ||
| } | ||
| } else { | ||
| $this->image->setOption( 'png:exclude-chunk', 'all' ); | ||
| } | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.