Skip to content

ImageMagick Handler is extremely slow. #6149

Closed
@colethorsen

Description

@colethorsen

PHP Version

7.4

CodeIgniter4 Version

4.2

CodeIgniter4 Installation Method

Composer (as dependency to an existing project)

Which operating systems have you tested for this bug?

macOS

Which server did you use?

apache

Database

MySQL 8

What happened?

Due to running commands multiple time through multiple exec calls and through unnecessarily setting the quality to 100 the implementation is greatly slowed down

Steps to Reproduce

The following code with a 712kb image is routinely taking over 14.5 seconds to execute.

$image = \Config\Services::image();

$image->withFile($path)
	->reorient()
	->resize(2400, 16, true)
	->save(null, 90);

Expected Output

The same image processed through ImageMagick using CodeIgniter 3 takes less than 2 seconds.

There are 2 primary differences. CodeIgniter 3 executes everything in one exec command instead of 2 in CodeIgnter 4, which brings up the second difference of when CodeIgniter 4 executes a command without a quality it sets it to 100.

Simply updating line 209 of the ImageMagickHandler from:

$cmd .= $action === '-version' ? ' ' . $action : ' -quality ' . $quality . ' ' . $action;

to:

$cmd .= $action === '-version' || $quality == 100 ? ' ' . $action : ' -quality ' . $quality . ' ' . $action;

Increases performance to just over 6 seconds.

However, doing this and batching the requests together so one is made instead of 2 from:

path/to/imagemagick/convert -quality 100  -resize 2400x1600 'image.png' 'image.png'
path/to/imagemagick/convert -quality 90 'image.png' 'image.png'

to:

path/to/imagemagick/convert -quality 90  -resize 2400x1600 'image.png' 'image.png'

increases performance back to CodeIgniter 3 levels of around 2 seconds.

Anything else?

I've implemented a custom ImageMagickHandler that does this successfully for my specific use cases, however I'm not sure if there are other cases where waiting until save is called to execute a list of commands that have been compiled would be unwanted, in which case the implementation of image handlers as a whole might have to be reconsidered.

i.e at the moment calling $image->resize(2400, 16, true); actually does something, where as in the case of my custom handler it just queues the command to be run when $image->save() is called.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementPRs that improve existing functionalities

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions