Opened 8 weeks ago
Closed 8 days ago
#63481 closed defect (bug) (worksforme)
WP_Image_Editor_Imagick takes longer time to upload image
Reported by: |
|
Owned by: | |
---|---|---|---|
Milestone: | Priority: | normal | |
Severity: | major | Version: | |
Component: | Media | Keywords: | close |
Focuses: | performance | Cc: |
Description
Has anyone faced issue where
WP_Image_Editor_Imagick
takes longer time to generate metadata/sizes?
Is this known issue?
Is there any ticket already?
A specific image (281kb) upload is taking around 45 second. Where other image is doing just fine, even larger one.
With WP_Image_Editor_GD works fast.
Attachments (1)
Change History (12)
#1
in reply to:
↑ description
@
7 weeks ago
#2
@
7 weeks ago
- Keywords reporter-feedback added
@alimuzzamanalim can you be more specific on how are you testing this?
What do you mean with "generate metadata" ?
#3
follow-up:
↓ 4
@
7 weeks ago
Here's a simplified test script which demonstrates the issue:
<?php $filename = '44.png'; $width = 1024; $height = 665; $image = new Imagick( $filename ); $image->resizeImage( $width, $height, Imagick::FILTER_TRIANGLE, 1 ); $start_time = hrtime( true) ; $colors = $image->getImageColors(); $end_time = hrtime( true ); $nanoseconds = $end_time - $start_time; $seconds = $nanoseconds / 1e9; echo 'Elapsed time: ' . sprintf( '%.3F', $seconds ) . "\n";
This takes almost 10 seconds on my machine.
#4
in reply to:
↑ 3
;
follow-up:
↓ 5
@
7 weeks ago
Replying to siliconforks:
Here's a simplified test script which demonstrates the issue:
<?php $filename = '44.png'; $width = 1024; $height = 665; $image = new Imagick( $filename ); $image->resizeImage( $width, $height, Imagick::FILTER_TRIANGLE, 1 ); $start_time = hrtime( true) ; $colors = $image->getImageColors(); $end_time = hrtime( true ); $nanoseconds = $end_time - $start_time; $seconds = $nanoseconds / 1e9; echo 'Elapsed time: ' . sprintf( '%.3F', $seconds ) . "\n";This takes almost 10 seconds on my machine.
But you are only using Imagick
here, not WP_Image_Editor_Imagick
.
Theoretically, we cannot control how much does it take to resize an image using a 3rd party library like this.
#5
in reply to:
↑ 4
@
7 weeks ago
Replying to SirLouen:
Theoretically, we cannot control how much does it take to resize an image using a 3rd party library like this.
I think it's mostly the call to getImageColors
(which was never done before [59589]) that is causing the performance issue.
Someone warned that getImageColors is slow almost a decade ago. It seems like this is still an issue with recent ImageMagick versions.
#6
@
7 weeks ago
@siliconforks the issue simply happens when you upload image from media library wp-admin/media-new.php and wp uses WP_Image_Editor_Imagick (checked in Site Health).
Sorry for the confusion.
#7
@
7 weeks ago
- Focuses performance added
- Keywords needs-patch 2nd-opinion added; reporter-feedback removed
#8
follow-up:
↓ 9
@
7 weeks ago
@SirLouen Not only the call to getImageColors
will be slow on a non-indexed PNG, but quantizeImage
is also likely adding a bit of overhead.
#9
in reply to:
↑ 8
@
7 weeks ago
Replying to nosilver4u:
@SirLouen Not only the call to
getImageColors
will be slow on a non-indexed PNG, butquantizeImage
is also likely adding a bit of overhead.
Maybe a bit ... But I think the main issue is that getImageColors
is just pathologically slow for some reason.
If I try calling quantizeImage
with a fixed hard-coded value (256) for the number of colors, it only seems to take maybe a few hundredths of a second. But if I try calling getImageColors
, that appears to be where the real problem is:
<?php $filename = '44.png'; $width = 1024; $height = 665; $output_filename = '44-1024x665.png'; $start_time = hrtime( true ) ; $image = new Imagick( $filename ); $image->resizeImage( $width, $height, Imagick::FILTER_TRIANGLE, 1 ); $image->writeImage( $output_filename ); $end_time = hrtime( true ); $nanoseconds = $end_time - $start_time; $seconds = $nanoseconds / 1e9; echo 'Size: ' . filesize( $output_filename ) . "\n"; echo 'Elapsed time: ' . sprintf( '%.3F', $seconds ) . "\n"; $output_filename = '44-1024x665-quantizeImage.png'; $start_time = hrtime( true ) ; $image = new Imagick( $filename ); $image->resizeImage( $width, $height, Imagick::FILTER_TRIANGLE, 1 ); $image->quantizeImage( 256, $image->getColorspace(), 0, false, false ); $image->writeImage( $output_filename ); $end_time = hrtime( true ); $nanoseconds = $end_time - $start_time; $seconds = $nanoseconds / 1e9; echo 'Size (quantizeImage): ' . filesize( $output_filename ) . "\n"; echo 'Elapsed time: ' . sprintf( '%.3F', $seconds ) . "\n"; $output_filename = '44-1024x665-getImageColors.png'; $start_time = hrtime( true ) ; $image = new Imagick( $filename ); $image->resizeImage( $width, $height, Imagick::FILTER_TRIANGLE, 1 ); $current_colors = $image->getImageColors(); $max_colors = min( 256, $current_colors ); $image->quantizeImage( $max_colors, $image->getColorspace(), 0, false, false ); $image->writeImage( $output_filename ); $end_time = hrtime( true ); $nanoseconds = $end_time - $start_time; $seconds = $nanoseconds / 1e9; echo 'Size (getImageColors): ' . filesize( $output_filename ) . "\n"; echo 'Elapsed time: ' . sprintf( '%.3F', $seconds ) . "\n";
The above code tries three different things:
- Resize the image without reducing the number of colors
- Resize the image calling
quantizeImage
with a fixed value of 256 - Resize the image calling
quantizeImage
with a value derived fromgetImageColors
This is the result I got:
Size: 505955 Elapsed time: 0.526 Size (quantizeImage): 185245 Elapsed time: 0.558 Size (getImageColors): 185245 Elapsed time: 10.328
#10
@
7 weeks ago
- Keywords close added; needs-patch 2nd-opinion removed
I've been reviewing the Imagick's source code for getImageColors
and it's an n2 complexity. The algorithm basically has to check every single pixel in the image to determine the number of colors, and it's a trustworthy operation, meaning they have not applied any sampling optimizations.
Currently, we could say that this report has been fixed because in [60246] we don't use this function any more. For this reason, I will say that we should bring this conversation back to where we are discussing the future of compression #63448, taking this observations by @siliconforks as new context and close this as worksforme
(fixed, in the current trunk
), to avoid having the conversation context divided between two threads.
Replying to alimuzzamanalim:
Not exactly, but there have been a number of ImageMagick-related issues since 6.8 was released - #63338, #63448. I suspect it is the same code which is causing all of these issues (originally introduced in changeset [59589]).
This may have been fixed already with a changeset made a few days ago: [60246].