Skip to content

imagick thumb driver: Requesting animated resized gifs from srcsets only applies alot of transforms (resize, crop etc) to the first frame #8096

Description

@mrckzgl

Description

I encountered a bug where if requesting an animated resized gif only its first frame is resized but the contents of the other frames is not resized.

This is caused by this code:

public function process(string $file, array $options = []): array
{
$options = $this->preprocess($file, $options);
$image = new Image($file);
$image = $this->threads($image, $options);
$image = $this->interlace($image, $options);
$image = $this->coalesce($image);
$image = $this->grayscale($image, $options);
$image = $this->autoOrient($image);
$image = $this->resize($image, $options);
$image = $this->quality($image, $options);
$image = $this->blur($image, $options);
$image = $this->sharpen($image, $options);
$image = $this->strip($image, $options);
if ($this->save($image, $file, $options) === false) {
// @codeCoverageIgnoreStart
throw new Exception(message: 'The imagemagick result could not be generated');
// @codeCoverageIgnoreEnd
}
return $options;

and
protected function coalesce(Image $image): Image
{
if ($image->getImageMimeType() === 'image/gif') {
return $image->coalesceImages();
}
return $image;
}

$image->coalesceImages(); will return an Imagick instance where its first frame is 'selected' and one needs to do all image transformation for all frames, but the driver is currently only doing it for the first.

Here is a (just briefly tested) fixed preprocess function:

	public function process(string $file, array $options = []): array
	{
		$options = $this->preprocess($file, $options);

		$image = new Image($file);
		$image = $this->threads($image, $options);
		$image = $this->interlace($image, $options);
		$image = $this->coalesce($image);
		foreach ($image as $frame) {
			$frame = $this->grayscale($image, $options);
			$frame = $this->autoOrient($image);
			$frame = $this->resize($image, $options);
			$frame = $this->quality($image, $options);
			$frame = $this->blur($image, $options);
			$frame = $this->sharpen($image, $options);
			$frame = $this->strip($image, $options);		
		}

		if ($this->save($image, $file, $options) === false) {
			// @codeCoverageIgnoreStart
			throw new Exception(message: 'The imagemagick result could not be generated');
			// @codeCoverageIgnoreEnd
		}

		return $options;
	}

Is there a way to register a custom / own thumb driver, such that we can patch this until a fix is released?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions