From d63b31da435745e6b5c30f2deb11ba14afb05383 Mon Sep 17 00:00:00 2001 From: Marcel Werk Date: Fri, 4 Aug 2023 16:28:15 +0200 Subject: [PATCH] Fix issues in the processing of animated WebP images see https://www.woltlab.com/community/thread/297233-fehler-bei-animierten-webp-grafiken/ --- .../adapter/ImagickImageAdapter.class.php | 26 ++++++++++++++----- 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/wcfsetup/install/files/lib/system/image/adapter/ImagickImageAdapter.class.php b/wcfsetup/install/files/lib/system/image/adapter/ImagickImageAdapter.class.php index 6d6f2cba7f..a5491672f3 100644 --- a/wcfsetup/install/files/lib/system/image/adapter/ImagickImageAdapter.class.php +++ b/wcfsetup/install/files/lib/system/image/adapter/ImagickImageAdapter.class.php @@ -46,6 +46,11 @@ class ImagickImageAdapter implements IImageAdapter, IWebpImageAdapter */ protected $supportsWritingAnimatedGIF = true; + /** + * List of image format that support animations. + */ + protected static array $animatedFormats = ['GIF', 'WEBP']; + /** * Creates a new ImagickImageAdapter. */ @@ -95,7 +100,7 @@ class ImagickImageAdapter implements IImageAdapter, IWebpImageAdapter // fix height/width for animated gifs as getImageHeight/getImageWidth // returns the height/width of ONE frame of the animated image, // not the "real" height/width of the image - if ($this->imagick->getImageFormat() == 'GIF') { + if (\in_array($this->imagick->getImageFormat(), self::$animatedFormats)) { $imagick = $this->imagick->coalesceImages(); $this->height = $imagick->getImageHeight(); @@ -126,7 +131,7 @@ class ImagickImageAdapter implements IImageAdapter, IWebpImageAdapter { $thumbnail = clone $this->imagick; - if ($thumbnail->getImageFormat() == 'GIF') { + if (\in_array($thumbnail->getImageFormat(), self::$animatedFormats)) { $thumbnail = $thumbnail->coalesceImages(); do { @@ -152,7 +157,7 @@ class ImagickImageAdapter implements IImageAdapter, IWebpImageAdapter */ public function clip($originX, $originY, $width, $height) { - if ($this->imagick->getImageFormat() == 'GIF') { + if (\in_array($this->imagick->getImageFormat(), self::$animatedFormats)) { $this->imagick = $this->imagick->coalesceImages(); do { @@ -169,7 +174,7 @@ class ImagickImageAdapter implements IImageAdapter, IWebpImageAdapter */ public function resize($originX, $originY, $originWidth, $originHeight, $targetWidth, $targetHeight) { - if ($this->imagick->getImageFormat() == 'GIF') { + if (\in_array($this->imagick->getImageFormat(), self::$animatedFormats)) { $image = $this->imagick->coalesceImages(); foreach ($image as $frame) { @@ -214,7 +219,7 @@ class ImagickImageAdapter implements IImageAdapter, IWebpImageAdapter // draw text $draw->annotation($x, $y, $text); - if ($this->imagick->getImageFormat() == 'GIF') { + if (\in_array($this->imagick->getImageFormat(), self::$animatedFormats)) { $this->imagick = $this->imagick->coalesceImages(); do { @@ -425,7 +430,7 @@ class ImagickImageAdapter implements IImageAdapter, IWebpImageAdapter $overlayImage->evaluateImage(\Imagick::EVALUATE_MULTIPLY, $opacity, \Imagick::CHANNEL_OPACITY); - if ($this->imagick->getImageFormat() == 'GIF') { + if (\in_array($this->imagick->getImageFormat(), self::$animatedFormats)) { $this->imagick = $this->imagick->coalesceImages(); do { @@ -521,6 +526,15 @@ class ImagickImageAdapter implements IImageAdapter, IWebpImageAdapter throw new \LogicException("Unreachable"); } + if ($image->getImageFormat() == 'WEBP' && $filename != 'webp') { + $sourceImage = $image; + $image = new \Imagick(); + foreach ($sourceImage as $frame) { + $image->addImage($frame->getImage()); + break; + } + } + $image->writeImages("{$fileFormat}:{$filename}", true); } -- 2.20.1