Skip to content

Conversation

@b1ink0
Copy link
Contributor

@b1ink0 b1ink0 commented Oct 30, 2025

Summary

Fixes #2237

Relevant technical choices

Prevents transparent backgrounds from being lost when converting PNG images to AVIF format on older ImageMagick

TODO:

  • Site health test

@b1ink0 b1ink0 added this to the webp-uploads n.e.x.t milestone Oct 30, 2025
@b1ink0 b1ink0 added [Type] Bug An existing feature is broken [Plugin] Modern Image Formats Issues for the Modern Image Formats plugin (formerly WebP Uploads) labels Oct 30, 2025
@codecov
Copy link

codecov bot commented Oct 30, 2025

Codecov Report

❌ Patch coverage is 8.45070% with 65 lines in your changes missing coverage. Please review.
✅ Project coverage is 68.31%. Comparing base (7938a41) to head (3fe6954).
⚠️ Report is 2 commits behind head on trunk.

Files with missing lines Patch % Lines
...ealth/imagick-avif-transparency-support/helper.php 0.00% 30 Missing ⚠️
plugins/webp-uploads/hooks.php 0.00% 24 Missing ⚠️
...health/imagick-avif-transparency-support/hooks.php 0.00% 5 Missing ⚠️
plugins/webp-uploads/helper.php 60.00% 4 Missing ⚠️
...gins/performance-lab/includes/site-health/load.php 0.00% 2 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##            trunk    #2245      +/-   ##
==========================================
- Coverage   68.86%   68.31%   -0.56%     
==========================================
  Files          90       92       +2     
  Lines        7610     7681      +71     
==========================================
+ Hits         5241     5247       +6     
- Misses       2369     2434      +65     
Flag Coverage Δ
multisite 68.31% <8.45%> (-0.56%) ⬇️
single 35.22% <8.45%> (-0.25%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

$imagick = $image_property->getValue( $editor );

if ( $imagick instanceof Imagick ) {
wp_cache_set( 'webp_uploads_image_has_transparency', (bool) $imagick->getImageAlphaChannel(), 'webp-uploads' );
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this set here in the cache since this function runs first and then later webp_uploads_get_image_output_format() runs to then read the value from the cache? This seems perhaps brittle. Normally setting and getting a cache value would happen in the context of the same function, not across separate functions, right? It feels like there may not be guarantees that the cached value would be set when it is checked for.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, it works but is definitely brittle. The other approach I can think of is using a global variable or a transient with a short expiration time to store the transparency status and hash of any uploaded file for the current request, and then using it in the webp_uploads_filter_image_editor_output_format to determine the output format. If you have any ideas for a temporary storage that can be used within the same request, I’d appreciate that.
@adamsilverstein if you also have a better idea to handle this case, I’d appreciate that as well.

Comment on lines +1004 to +1009
$reflection = new ReflectionClass( $editor );
$image_property = $reflection->getProperty( 'image' );
if ( PHP_VERSION_ID < 80100 ) {
$image_property->setAccessible( true );
}
$imagick = $image_property->getValue( $editor );
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's too bad that the image property is protected. Note how in the Image Placeholder plugin it actually extends WP_Image_Editor_Imagick with a Dominant_Color_Image_Editor_Imagick which it then uses. This is problematic though since multiple plugins can't each register their own editor classes.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did try to create an anonymous class and added a method to expose the image property, but the Reflection API seemed better.

function webp_uploads_imagick_avif_transparency_supported(): bool {
if ( extension_loaded( 'imagick' ) && class_exists( 'Imagick' ) ) {
$imagick_version = Imagick::getVersion();
if ( (bool) preg_match( '/((?:[0-9]+\\.?)+)/', $imagick_version['versionString'], $matches ) ) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if ( (bool) preg_match( '/((?:[0-9]+\\.?)+)/', $imagick_version['versionString'], $matches ) ) {
if ( (bool) preg_match( '/^\d+(?:\.\d+)+$/', $imagick_version['versionString'], $matches ) ) {

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated regex to /\d+(?:\.\d+)+(?:-\d+)?/ for handling version string like this:

ImageMagick 7.1.1-15 Q16 aarch64 98eceff6a:20230729 https://imagemagick.org

Copy link
Contributor Author

@b1ink0 b1ink0 Nov 14, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it make more sense to move this Site Health test to the Modern Image Formats plugin?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

[Plugin] Modern Image Formats Issues for the Modern Image Formats plugin (formerly WebP Uploads) [Type] Bug An existing feature is broken

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Transparent backgrounds lost when converting to AVIF under certain conditions

2 participants