From 1e21c15a68d0d6778ef5b4213ffad8ee45bd81a7 Mon Sep 17 00:00:00 2001 From: ADmad Date: Wed, 18 Dec 2024 22:26:40 +0530 Subject: [PATCH] Ensure original type is preserved when `fm` is not specified. Earlier, if `fm` was not specified then an image with mime-type "image/x-webp" would get encoded as jpg instead of webp, since the mime type is not include in the Encoder::supportedFormats() list. --- src/Api/Encoder.php | 14 +++++++--- tests/Api/EncoderTest.php | 58 ++++++++++++++++++--------------------- 2 files changed, 36 insertions(+), 36 deletions(-) diff --git a/src/Api/Encoder.php b/src/Api/Encoder.php index 80aad01..c23af26 100644 --- a/src/Api/Encoder.php +++ b/src/Api/Encoder.php @@ -6,6 +6,7 @@ use Intervention\Image\Interfaces\EncodedImageInterface; use Intervention\Image\Interfaces\ImageInterface; +use Intervention\Image\MediaType; /** * Encoder Api class to convert a given image to a specific format. @@ -102,13 +103,18 @@ public function run(ImageInterface $image): EncodedImageInterface public function getFormat(ImageInterface $image): string { $fm = (string) $this->getParam('fm'); + if ($fm) { + return array_key_exists($fm, static::supportedFormats()) ? $fm : 'jpg'; + } - if ($fm && array_key_exists($fm, static::supportedFormats())) { - return $fm; + $mediaType = MediaType::tryFrom($image->origin()->mediaType()); + if ($mediaType === null) { + return 'jpg'; } - /** @psalm-suppress RiskyTruthyFalsyComparison */ - return array_search($image->origin()->mediaType(), static::supportedFormats(), true) ?: 'jpg'; + $fm = $mediaType->format()->fileExtension()->value; + + return array_key_exists($fm, static::supportedFormats()) ? $fm : 'jpg'; } /** diff --git a/tests/Api/EncoderTest.php b/tests/Api/EncoderTest.php index 6a4723a..025d10a 100644 --- a/tests/Api/EncoderTest.php +++ b/tests/Api/EncoderTest.php @@ -107,48 +107,42 @@ public function testRun(): void public function testGetFormat(): void { - /** - * @psalm-suppress MissingClosureParamType - */ - $image = \Mockery::mock(ImageInterface::class, function ($mock) { - /* - * @var Mock $mock - */ - $this->assertMediaType($mock, 'image/jpeg')->once(); - $this->assertMediaType($mock, 'image/png')->once(); - $this->assertMediaType($mock, 'image/gif')->once(); - $this->assertMediaType($mock, 'image/bmp')->once(); - $this->assertMediaType($mock, 'image/jpeg')->twice(); - - if (function_exists('imagecreatefromwebp')) { - $this->assertMediaType($mock, 'image/webp')->once(); - } - - if (function_exists('imagecreatefromavif')) { - $this->assertMediaType($mock, 'image/avif')->once(); - } - }); + $this->assertSame('jpg', $this->encoder->setParams(['fm' => 'jpg'])->getFormat($this->getImageByMimeType('image/jpeg'))); + $this->assertSame('png', $this->encoder->setParams(['fm' => 'png'])->getFormat($this->getImageByMimeType('image/png'))); + $this->assertSame('gif', $this->encoder->setParams(['fm' => 'gif'])->getFormat($this->getImageByMimeType('image/gif'))); + + // Make sure 'fm' parameter takes precedence + $this->assertSame('png', $this->encoder->setParams(['fm' => 'png'])->getFormat($this->getImageByMimeType('image/jpeg'))); + $this->assertSame('gif', $this->encoder->setParams(['fm' => 'gif'])->getFormat($this->getImageByMimeType('image/jpeg'))); + $this->assertSame('pjpg', $this->encoder->setParams(['fm' => 'pjpg'])->getFormat($this->getImageByMimeType('image/jpeg'))); - $this->assertSame('jpg', $this->encoder->setParams(['fm' => 'jpg'])->getFormat($image)); - $this->assertSame('png', $this->encoder->setParams(['fm' => 'png'])->getFormat($image)); - $this->assertSame('gif', $this->encoder->setParams(['fm' => 'gif'])->getFormat($image)); - $this->assertSame('jpg', $this->encoder->setParams(['fm' => null])->getFormat($image)); - $this->assertSame('png', $this->encoder->setParams(['fm' => null])->getFormat($image)); - $this->assertSame('gif', $this->encoder->setParams(['fm' => null])->getFormat($image)); - $this->assertSame('jpg', $this->encoder->setParams(['fm' => null])->getFormat($image)); + // Make sure we keep the current format if no format is provided + $this->assertSame('jpg', $this->encoder->setParams(['fm' => null])->getFormat($this->getImageByMimeType('image/jpeg'))); + $this->assertSame('png', $this->encoder->setParams(['fm' => null])->getFormat($this->getImageByMimeType('image/png'))); + $this->assertSame('gif', $this->encoder->setParams(['fm' => null])->getFormat($this->getImageByMimeType('image/gif'))); - $this->assertSame('jpg', $this->encoder->setParams(['fm' => ''])->getFormat($image)); - $this->assertSame('jpg', $this->encoder->setParams(['fm' => 'invalid'])->getFormat($image)); + $this->assertSame('jpg', $this->encoder->setParams(['fm' => ''])->getFormat($this->getImageByMimeType('image/jpeg'))); + $this->assertSame('png', $this->encoder->setParams(['fm' => ''])->getFormat($this->getImageByMimeType('image/png'))); + $this->assertSame('jpg', $this->encoder->setParams(['fm' => 'invalid'])->getFormat($this->getImageByMimeType('image/png'))); if (function_exists('imagecreatefromwebp')) { - $this->assertSame('webp', $this->encoder->setParams(['fm' => null])->getFormat($image)); + $this->assertSame('webp', $this->encoder->setParams(['fm' => null])->getFormat($this->getImageByMimeType('image/webp'))); + $this->assertSame('webp', $this->encoder->setParams(['fm' => 'webp'])->getFormat($this->getImageByMimeType('image/jpeg'))); } if (function_exists('imagecreatefromavif')) { - $this->assertSame('avif', $this->encoder->setParams(['fm' => null])->getFormat($image)); + $this->assertSame('avif', $this->encoder->setParams(['fm' => null])->getFormat($this->getImageByMimeType('image/avif'))); + $this->assertSame('avif', $this->encoder->setParams(['fm' => 'avif'])->getFormat($this->getImageByMimeType('image/jpeg'))); } } + protected function getImageByMimeType(string $mimeType): ImageInterface + { + return \Mockery::mock(ImageInterface::class, function ($mock) use ($mimeType) { + $this->assertMediaType($mock, $mimeType); + }); + } + public function testGetQuality(): void { $this->assertSame(100, $this->encoder->setParams(['q' => '100'])->getQuality());