Skip to content

Commit

Permalink
Ensure original type is preserved when fm is not specified.
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
ADmad committed Dec 19, 2024
1 parent 3cb6c58 commit 1e21c15
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 36 deletions.
14 changes: 10 additions & 4 deletions src/Api/Encoder.php
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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';
}

/**
Expand Down
58 changes: 26 additions & 32 deletions tests/Api/EncoderTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -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());
Expand Down

0 comments on commit 1e21c15

Please sign in to comment.