diff --git a/composer.json b/composer.json
index e6d578c9..1d4f2061 100644
--- a/composer.json
+++ b/composer.json
@@ -27,7 +27,7 @@
],
"require": {
"php": "^8.1",
- "intervention/image": "^3.3",
+ "intervention/image": "^3.6",
"league/flysystem": "^3.0",
"psr/http-message": "^1.0|^2.0"
},
diff --git a/docs/3.0/api/progressive-interlaced.md b/docs/3.0/api/progressive-interlaced.md
new file mode 100644
index 00000000..e946a0fd
--- /dev/null
+++ b/docs/3.0/api/progressive-interlaced.md
@@ -0,0 +1,26 @@
+---
+layout: default
+title: Progressive & Interlaced
+---
+
+## Progressive & Interlaced Images
+
+## Interlace `interlace`
+
+The `interlace` parameter controls whether an image is rendered in a progressive or interlaced format. This feature enhances the loading experience of images, making them appear gradually as they are downloaded, which can improve the user experience on slower connections.
+
+> Caution: For GIF/PNG, it can generate a slightly larger file size.
+
+### Supported Formats
+
+- **JPG**: The `onterlace` parameter applies a progressive scan to JPG images.
+- **PNG** and **GIF**: The `interlace` parameter enables interlacing for GIF/PNG images.
+
+> Note: When `ext` is set to `.pjpg`, it will automatically generate a progressive JPG image, regardless of the `interlace` parameter.
+
+~~~ html
+
+
+~~~
+
+[![© Photo Joel Reynolds](https://glide.herokuapp.com/1.0/kayaks.jpg?interlace=1)](https://glide.herokuapp.com/1.0/kayaks.jpg?interlace=1)
diff --git a/docs/3.0/config/setup.md b/docs/3.0/config/setup.md
index f52e2129..e94728ad 100644
--- a/docs/3.0/config/setup.md
+++ b/docs/3.0/config/setup.md
@@ -77,7 +77,6 @@ $manipulators = [
new League\Glide\Manipulators\Watermark($watermarks),
new League\Glide\Manipulators\Background(),
new League\Glide\Manipulators\Border(),
- new League\Glide\Manipulators\Encode(),
];
// Set API
diff --git a/docs/_data/menu.yml b/docs/_data/menu.yml
index 5aced23a..9a7065c2 100644
--- a/docs/_data/menu.yml
+++ b/docs/_data/menu.yml
@@ -25,6 +25,7 @@
Background: '/3.0/api/background/'
Border: '/3.0/api/border/'
Encode: '/3.0/api/encode/'
+ Progressive & Interlaced: '/3.0/api/progressive-interlaced/'
'2.0':
Getting Started:
Introduction: '/'
diff --git a/src/Api/Api.php b/src/Api/Api.php
index 42799a29..45be6f99 100644
--- a/src/Api/Api.php
+++ b/src/Api/Api.php
@@ -3,6 +3,7 @@
namespace League\Glide\Api;
use Intervention\Image\ImageManager;
+use Intervention\Image\Interfaces\ImageInterface;
use League\Glide\Manipulators\ManipulatorInterface;
class Api implements ApiInterface
@@ -91,10 +92,25 @@ public function run(string $source, array $params): string
foreach ($this->manipulators as $manipulator) {
$manipulator->setParams($params);
-
$image = $manipulator->run($image);
}
- return $image->encodeByMediaType()->toString();
+ return $this->encode($image, $params);
+ }
+
+ /**
+ * Perform image encoding to a given format.
+ *
+ * @param ImageInterface $image Image object
+ * @param array $params the manipulator params
+ *
+ * @return string Manipulated image binary data
+ */
+ public function encode(ImageInterface $image, array $params): string
+ {
+ $encoder = new Encoder($params);
+ $encoded = $encoder->run($image);
+
+ return $encoded->toString();
}
}
diff --git a/src/Api/Encoder.php b/src/Api/Encoder.php
new file mode 100644
index 00000000..bef473b2
--- /dev/null
+++ b/src/Api/Encoder.php
@@ -0,0 +1,151 @@
+params = $params;
+ }
+
+ /**
+ * Set the manipulation params.
+ *
+ * @param array $params The manipulation params.
+ *
+ * @return $this
+ */
+ public function setParams(array $params)
+ {
+ $this->params = $params;
+
+ return $this;
+ }
+
+ /**
+ * Get a specific manipulation param.
+ */
+ public function getParam(string $name): mixed
+ {
+ return array_key_exists($name, $this->params)
+ ? $this->params[$name]
+ : null;
+ }
+
+ /**
+ * Perform output image manipulation.
+ *
+ * @param ImageInterface $image The source image.
+ *
+ * @return EncodedImageInterface The encoded image.
+ */
+ public function run(ImageInterface $image): EncodedImageInterface
+ {
+ $format = $this->getFormat($image);
+ $quality = $this->getQuality();
+ $shouldInterlace = filter_var($this->getParam('interlace'), FILTER_VALIDATE_BOOLEAN);
+
+ if ('pjpg' === $format) {
+ $shouldInterlace = true;
+ $format = 'jpg';
+ }
+
+ $encoderOptions = ['extension' => $format];
+ switch ($format) {
+ case 'avif':
+ case 'heic':
+ case 'tiff':
+ case 'webp':
+ $encoderOptions['quality'] = $quality;
+ break;
+ case 'jpg':
+ $encoderOptions['quality'] = $quality;
+ $encoderOptions['progressive'] = $shouldInterlace;
+ break;
+ case 'gif':
+ case 'png':
+ $encoderOptions['interlaced'] = $shouldInterlace;
+ break;
+ default:
+ throw new \Exception("Invalid format provided: {$format}");
+ }
+
+ return $image->encodeByExtension(...$encoderOptions);
+ }
+
+ /**
+ * Resolve format.
+ *
+ * @param ImageInterface $image The source image.
+ *
+ * @return string The resolved format.
+ */
+ public function getFormat(ImageInterface $image): string
+ {
+ $fm = (string) $this->getParam('fm');
+
+ if ($fm && array_key_exists($fm, static::supportedFormats())) {
+ return $fm;
+ }
+
+ /** @psalm-suppress RiskyTruthyFalsyComparison */
+ return array_search($image->origin()->mediaType(), static::supportedFormats(), true) ?: 'jpg';
+ }
+
+ /**
+ * Get a list of supported image formats and MIME types.
+ *
+ * @return array
+ */
+ public static function supportedFormats(): array
+ {
+ return [
+ 'avif' => 'image/avif',
+ 'gif' => 'image/gif',
+ 'jpg' => 'image/jpeg',
+ 'pjpg' => 'image/jpeg',
+ 'png' => 'image/png',
+ 'webp' => 'image/webp',
+ 'tiff' => 'image/tiff',
+ 'heic' => 'image/heic',
+ ];
+ }
+
+ /**
+ * Resolve quality.
+ *
+ * @return int The resolved quality.
+ */
+ public function getQuality(): int
+ {
+ $default = 90;
+ $q = $this->getParam('q');
+
+ if (
+ !is_numeric($q)
+ || $q < 0
+ || $q > 100
+ ) {
+ return $default;
+ }
+
+ return (int) $q;
+ }
+}
diff --git a/src/Manipulators/Encode.php b/src/Manipulators/Encode.php
deleted file mode 100644
index 1ce47de2..00000000
--- a/src/Manipulators/Encode.php
+++ /dev/null
@@ -1,114 +0,0 @@
-getFormat($image);
- $quality = $this->getQuality();
- $driver = $image->driver();
- $interlace = false;
-
- if ('pjpg' === $format) {
- $interlace = true;
-
- $format = 'jpg';
- }
-
- $image = (new ImageManager($driver))->read(
- $image->encodeByExtension($format, quality: $quality)->toString()
- );
-
- if ($interlace) {
- $image = $this->interlace($image, $driver);
- }
-
- return $image;
- }
-
- /**
- * Resolve format.
- *
- * @param ImageInterface $image The source image.
- *
- * @return string The resolved format.
- */
- public function getFormat(ImageInterface $image): string
- {
- $fm = (string) $this->getParam('fm');
-
- if ($fm && array_key_exists($fm, static::supportedFormats())) {
- return $fm;
- }
-
- /** @psalm-suppress RiskyTruthyFalsyComparison */
- return array_search($image->origin()->mediaType(), static::supportedFormats(), true) ?: 'jpg';
- }
-
- /**
- * Get a list of supported image formats and MIME types.
- *
- * @return array
- */
- public static function supportedFormats(): array
- {
- return [
- 'avif' => 'image/avif',
- 'gif' => 'image/gif',
- 'jpg' => 'image/jpeg',
- 'pjpg' => 'image/jpeg',
- 'png' => 'image/png',
- 'webp' => 'image/webp',
- 'tiff' => 'image/tiff',
- 'heic' => 'image/heic',
- ];
- }
-
- /**
- * Resolve quality.
- *
- * @return int The resolved quality.
- */
- public function getQuality(): int
- {
- $default = 90;
- $q = $this->getParam('q');
-
- if (!is_numeric($q)
- || $q < 0
- || $q > 100
- ) {
- return $default;
- }
-
- return (int) $q;
- }
-
- protected function interlace(ImageInterface $image, DriverInterface $driver): ImageInterface
- {
- $img = $image->core()->native();
-
- if ($driver instanceof ImagickDriver) {
- $img->setInterlaceScheme(\Imagick::INTERLACE_PLANE);
- } elseif ($driver instanceof GdDriver) {
- imageinterlace($img, true);
- }
-
- return $image;
- }
-}
diff --git a/src/ServerFactory.php b/src/ServerFactory.php
index eb08e7b4..d2e9acc5 100644
--- a/src/ServerFactory.php
+++ b/src/ServerFactory.php
@@ -13,7 +13,6 @@
use League\Glide\Manipulators\Brightness;
use League\Glide\Manipulators\Contrast;
use League\Glide\Manipulators\Crop;
-use League\Glide\Manipulators\Encode;
use League\Glide\Manipulators\Filter;
use League\Glide\Manipulators\Flip;
use League\Glide\Manipulators\Gamma;
@@ -255,7 +254,6 @@ public function getManipulators(): array
new Watermark($this->getWatermarks(), $this->getWatermarksPathPrefix() ?? ''),
new Background(),
new Border(),
- new Encode(),
];
}
diff --git a/tests/Api/ApiTest.php b/tests/Api/ApiTest.php
index da3b58cc..c55b2c15 100644
--- a/tests/Api/ApiTest.php
+++ b/tests/Api/ApiTest.php
@@ -61,7 +61,11 @@ public function testGetManipulators()
public function testRun()
{
$image = \Mockery::mock(ImageInterface::class, function ($mock) {
- $mock->shouldReceive('encodeByMediaType')->andReturn(\Mockery::mock(EncodedImageInterface::class, function ($mock) {
+ $mock->shouldReceive('origin')->andReturn(\Mockery::mock('\Intervention\Image\Origin', function ($mock) {
+ $mock->shouldReceive('mediaType')->andReturn('image/png');
+ }));
+
+ $mock->shouldReceive('encodeByExtension')->with('png')->andReturn(\Mockery::mock(EncodedImageInterface::class, function ($mock) {
$mock->shouldReceive('toString')->andReturn('encoded');
}));
});
diff --git a/tests/Api/EncoderTest.php b/tests/Api/EncoderTest.php
new file mode 100644
index 00000000..b3bae46c
--- /dev/null
+++ b/tests/Api/EncoderTest.php
@@ -0,0 +1,224 @@
+jpg = $manager->read(
+ $manager->create(100, 100)->encode(new MediaTypeEncoder('image/jpeg'))->toFilePointer()
+ );
+ $this->png = $manager->read(
+ $manager->create(100, 100)->encode(new MediaTypeEncoder('image/png'))->toFilePointer()
+ );
+ $this->gif = $manager->read(
+ $manager->create(100, 100)->encode(new MediaTypeEncoder('image/gif'))->toFilePointer()
+ );
+
+ if (function_exists('imagecreatefromwebp')) {
+ $this->webp = $manager->read(
+ $manager->create(100, 100)->encode(new MediaTypeEncoder('image/webp'))->toFilePointer()
+ );
+ }
+
+ if (function_exists('imagecreatefromavif')) {
+ $this->avif = $manager->read(
+ $manager->create(100, 100)->encode(new MediaTypeEncoder('image/avif'))->toFilePointer()
+ );
+ }
+
+ $this->encoder = new Encoder();
+ }
+
+ public function tearDown(): void
+ {
+ \Mockery::close();
+ }
+
+ public function testCreateInstance(): void
+ {
+ /**
+ * @psalm-suppress ArgumentTypeCoercion
+ */
+ $this->assertInstanceOf(Encoder::class, $this->encoder);
+ }
+
+ public function testRun(): void
+ {
+ $this->assertSame('image/jpeg', $this->getMime($this->encoder->setParams(['fm' => 'jpg'])->run($this->jpg)));
+ $this->assertSame('image/jpeg', $this->getMime($this->encoder->setParams(['fm' => 'jpg'])->run($this->png)));
+ $this->assertSame('image/jpeg', $this->getMime($this->encoder->setParams(['fm' => 'jpg'])->run($this->gif)));
+ $this->assertSame('image/jpeg', $this->getMime($this->encoder->setParams(['fm' => 'pjpg'])->run($this->jpg)));
+ $this->assertSame('image/jpeg', $this->getMime($this->encoder->setParams(['fm' => 'pjpg'])->run($this->png)));
+ $this->assertSame('image/jpeg', $this->getMime($this->encoder->setParams(['fm' => 'pjpg'])->run($this->gif)));
+ $this->assertSame('image/png', $this->getMime($this->encoder->setParams(['fm' => 'png'])->run($this->jpg)));
+ $this->assertSame('image/png', $this->getMime($this->encoder->setParams(['fm' => 'png'])->run($this->png)));
+ $this->assertSame('image/png', $this->getMime($this->encoder->setParams(['fm' => 'png'])->run($this->gif)));
+ $this->assertSame('image/gif', $this->getMime($this->encoder->setParams(['fm' => 'gif'])->run($this->jpg)));
+ $this->assertSame('image/gif', $this->getMime($this->encoder->setParams(['fm' => 'gif'])->run($this->png)));
+ $this->assertSame('image/gif', $this->getMime($this->encoder->setParams(['fm' => 'gif'])->run($this->gif)));
+
+ if (function_exists('imagecreatefromwebp')) {
+ $this->assertSame('image/jpeg', $this->getMime($this->encoder->setParams(['fm' => 'jpg'])->run($this->webp)));
+ $this->assertSame('image/jpeg', $this->getMime($this->encoder->setParams(['fm' => 'pjpg'])->run($this->webp)));
+ $this->assertSame('image/png', $this->getMime($this->encoder->setParams(['fm' => 'png'])->run($this->webp)));
+ $this->assertSame('image/gif', $this->getMime($this->encoder->setParams(['fm' => 'gif'])->run($this->webp)));
+ $this->assertSame('image/webp', $this->getMime($this->encoder->setParams(['fm' => 'webp'])->run($this->jpg)));
+ $this->assertSame('image/webp', $this->getMime($this->encoder->setParams(['fm' => 'webp'])->run($this->png)));
+ $this->assertSame('image/webp', $this->getMime($this->encoder->setParams(['fm' => 'webp'])->run($this->gif)));
+ $this->assertSame('image/webp', $this->getMime($this->encoder->setParams(['fm' => 'webp'])->run($this->webp)));
+ }
+ if (function_exists('imagecreatefromavif')) {
+ $this->assertSame('image/jpeg', $this->getMime($this->encoder->setParams(['fm' => 'jpg'])->run($this->avif)));
+ $this->assertSame('image/jpeg', $this->getMime($this->encoder->setParams(['fm' => 'pjpg'])->run($this->avif)));
+ $this->assertSame('image/png', $this->getMime($this->encoder->setParams(['fm' => 'png'])->run($this->avif)));
+ $this->assertSame('image/gif', $this->getMime($this->encoder->setParams(['fm' => 'gif'])->run($this->avif)));
+ $this->assertSame('image/avif', $this->getMime($this->encoder->setParams(['fm' => 'avif'])->run($this->jpg)));
+ $this->assertSame('image/avif', $this->getMime($this->encoder->setParams(['fm' => 'avif'])->run($this->png)));
+ $this->assertSame('image/avif', $this->getMime($this->encoder->setParams(['fm' => 'avif'])->run($this->gif)));
+ $this->assertSame('image/avif', $this->getMime($this->encoder->setParams(['fm' => 'avif'])->run($this->avif)));
+ }
+
+ if (function_exists('imagecreatefromwebp') && function_exists('imagecreatefromavif')) {
+ $this->assertSame('image/webp', $this->getMime($this->encoder->setParams(['fm' => 'webp'])->run($this->avif)));
+ $this->assertSame('image/avif', $this->getMime($this->encoder->setParams(['fm' => 'avif'])->run($this->webp)));
+ }
+ }
+
+ 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($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));
+
+ $this->assertSame('jpg', $this->encoder->setParams(['fm' => ''])->getFormat($image));
+ $this->assertSame('jpg', $this->encoder->setParams(['fm' => 'invalid'])->getFormat($image));
+
+ if (function_exists('imagecreatefromwebp')) {
+ $this->assertSame('webp', $this->encoder->setParams(['fm' => null])->getFormat($image));
+ }
+
+ if (function_exists('imagecreatefromavif')) {
+ $this->assertSame('avif', $this->encoder->setParams(['fm' => null])->getFormat($image));
+ }
+ }
+
+ public function testGetQuality(): void
+ {
+ $this->assertSame(100, $this->encoder->setParams(['q' => '100'])->getQuality());
+ $this->assertSame(100, $this->encoder->setParams(['q' => 100])->getQuality());
+ $this->assertSame(90, $this->encoder->setParams(['q' => null])->getQuality());
+ $this->assertSame(90, $this->encoder->setParams(['q' => 'a'])->getQuality());
+ $this->assertSame(50, $this->encoder->setParams(['q' => '50.50'])->getQuality());
+ $this->assertSame(90, $this->encoder->setParams(['q' => '-1'])->getQuality());
+ $this->assertSame(90, $this->encoder->setParams(['q' => '101'])->getQuality());
+ }
+
+ /**
+ * Test functions that require the imagick extension.
+ */
+ public function testWithImagick(): void
+ {
+ if (!extension_loaded('imagick')) {
+ $this->markTestSkipped(
+ 'The imagick extension is not available.'
+ );
+ }
+ $manager = ImageManager::imagick();
+ // These need to be recreated with the imagick driver selected in the manager
+ $this->jpg = $manager->read($manager->create(100, 100)->encode(new MediaTypeEncoder('image/jpeg'))->toFilePointer());
+ $this->png = $manager->read($manager->create(100, 100)->encode(new MediaTypeEncoder('image/png'))->toFilePointer());
+ $this->gif = $manager->read($manager->create(100, 100)->encode(new MediaTypeEncoder('image/gif'))->toFilePointer());
+ $this->heic = $manager->read($manager->create(100, 100)->encode(new MediaTypeEncoder('image/heic'))->toFilePointer());
+ $this->tif = $manager->read($manager->create(100, 100)->encode(new MediaTypeEncoder('image/tiff'))->toFilePointer());
+
+ $this->assertSame('image/tiff', $this->getMime($this->encoder->setParams(['fm' => 'tiff'])->run($this->jpg)));
+ $this->assertSame('image/tiff', $this->getMime($this->encoder->setParams(['fm' => 'tiff'])->run($this->png)));
+ $this->assertSame('image/tiff', $this->getMime($this->encoder->setParams(['fm' => 'tiff'])->run($this->gif)));
+ $this->assertSame('image/tiff', $this->getMime($this->encoder->setParams(['fm' => 'tiff'])->run($this->heic)));
+ }
+
+ public function testSupportedFormats(): void
+ {
+ $expected = [
+ 'avif' => 'image/avif',
+ 'gif' => 'image/gif',
+ 'jpg' => 'image/jpeg',
+ 'pjpg' => 'image/jpeg',
+ 'png' => 'image/png',
+ 'webp' => 'image/webp',
+ 'tiff' => 'image/tiff',
+ 'heic' => 'image/heic',
+ ];
+
+ $this->assertSame($expected, Encoder::supportedFormats());
+ }
+
+ protected function getMime(EncodedImageInterface $image): string
+ {
+ return $image->mediaType();
+ }
+
+ /**
+ * Creates an assertion to check media type.
+ *
+ * @param Mock $mock
+ * @param string $mediaType
+ *
+ * @psalm-suppress MoreSpecificReturnType
+ */
+ protected function assertMediaType($mock, $mediaType): Mockery\CompositeExpectation
+ {
+ /*
+ * @var Mock $mock
+ */
+ /**
+ * @psalm-suppress LessSpecificReturnStatement, UndefinedMagicMethod
+ */
+ return $mock->shouldReceive('origin')->andReturn(\Mockery::mock('Intervention\Image\Origin', ['mediaType' => $mediaType]));
+ }
+}
diff --git a/tests/Manipulators/EncodeTest.php b/tests/Manipulators/EncodeTest.php
deleted file mode 100644
index f3a5d1d6..00000000
--- a/tests/Manipulators/EncodeTest.php
+++ /dev/null
@@ -1,195 +0,0 @@
-jpg = $manager->read(
- $manager->create(100, 100)->encode(new MediaTypeEncoder('image/jpeg'))->toFilePointer()
- );
- $this->png = $manager->read(
- $manager->create(100, 100)->encode(new MediaTypeEncoder('image/png'))->toFilePointer()
- );
- $this->gif = $manager->read(
- $manager->create(100, 100)->encode(new MediaTypeEncoder('image/gif'))->toFilePointer()
- );
-
- if (function_exists('imagecreatefromwebp')) {
- $this->webp = $manager->read(
- $manager->create(100, 100)->encode(new MediaTypeEncoder('image/webp'))->toFilePointer()
- );
- }
-
- if (function_exists('imagecreatefromavif')) {
- $this->avif = $manager->read(
- $manager->create(100, 100)->encode(new MediaTypeEncoder('image/avif'))->toFilePointer()
- );
- }
-
- $this->manipulator = new Encode();
- }
-
- public function tearDown(): void
- {
- \Mockery::close();
- }
-
- public function testCreateInstance()
- {
- $this->assertInstanceOf('League\Glide\Manipulators\Encode', $this->manipulator);
- }
-
- public function testRun()
- {
- $this->assertSame('image/jpeg', $this->getMime($this->manipulator->setParams(['fm' => 'jpg'])->run($this->jpg)));
- $this->assertSame('image/jpeg', $this->getMime($this->manipulator->setParams(['fm' => 'jpg'])->run($this->png)));
- $this->assertSame('image/jpeg', $this->getMime($this->manipulator->setParams(['fm' => 'jpg'])->run($this->gif)));
- $this->assertSame('image/jpeg', $this->getMime($this->manipulator->setParams(['fm' => 'pjpg'])->run($this->jpg)));
- $this->assertSame('image/jpeg', $this->getMime($this->manipulator->setParams(['fm' => 'pjpg'])->run($this->png)));
- $this->assertSame('image/jpeg', $this->getMime($this->manipulator->setParams(['fm' => 'pjpg'])->run($this->gif)));
- $this->assertSame('image/png', $this->getMime($this->manipulator->setParams(['fm' => 'png'])->run($this->jpg)));
- $this->assertSame('image/png', $this->getMime($this->manipulator->setParams(['fm' => 'png'])->run($this->png)));
- $this->assertSame('image/png', $this->getMime($this->manipulator->setParams(['fm' => 'png'])->run($this->gif)));
- $this->assertSame('image/gif', $this->getMime($this->manipulator->setParams(['fm' => 'gif'])->run($this->jpg)));
- $this->assertSame('image/gif', $this->getMime($this->manipulator->setParams(['fm' => 'gif'])->run($this->png)));
- $this->assertSame('image/gif', $this->getMime($this->manipulator->setParams(['fm' => 'gif'])->run($this->gif)));
-
- if (function_exists('imagecreatefromwebp')) {
- $this->assertSame('image/jpeg', $this->getMime($this->manipulator->setParams(['fm' => 'jpg'])->run($this->webp)));
- $this->assertSame('image/jpeg', $this->getMime($this->manipulator->setParams(['fm' => 'pjpg'])->run($this->webp)));
- $this->assertSame('image/png', $this->getMime($this->manipulator->setParams(['fm' => 'png'])->run($this->webp)));
- $this->assertSame('image/gif', $this->getMime($this->manipulator->setParams(['fm' => 'gif'])->run($this->webp)));
- $this->assertSame('image/webp', $this->getMime($this->manipulator->setParams(['fm' => 'webp'])->run($this->jpg)));
- $this->assertSame('image/webp', $this->getMime($this->manipulator->setParams(['fm' => 'webp'])->run($this->png)));
- $this->assertSame('image/webp', $this->getMime($this->manipulator->setParams(['fm' => 'webp'])->run($this->gif)));
- $this->assertSame('image/webp', $this->getMime($this->manipulator->setParams(['fm' => 'webp'])->run($this->webp)));
- }
- if (function_exists('imagecreatefromavif')) {
- $this->assertSame('image/jpeg', $this->getMime($this->manipulator->setParams(['fm' => 'jpg'])->run($this->avif)));
- $this->assertSame('image/jpeg', $this->getMime($this->manipulator->setParams(['fm' => 'pjpg'])->run($this->avif)));
- $this->assertSame('image/png', $this->getMime($this->manipulator->setParams(['fm' => 'png'])->run($this->avif)));
- $this->assertSame('image/gif', $this->getMime($this->manipulator->setParams(['fm' => 'gif'])->run($this->avif)));
- $this->assertSame('image/avif', $this->getMime($this->manipulator->setParams(['fm' => 'avif'])->run($this->jpg)));
- $this->assertSame('image/avif', $this->getMime($this->manipulator->setParams(['fm' => 'avif'])->run($this->png)));
- $this->assertSame('image/avif', $this->getMime($this->manipulator->setParams(['fm' => 'avif'])->run($this->gif)));
- $this->assertSame('image/avif', $this->getMime($this->manipulator->setParams(['fm' => 'avif'])->run($this->avif)));
- }
-
- if (function_exists('imagecreatefromwebp') && function_exists('imagecreatefromavif')) {
- $this->assertSame('image/webp', $this->getMime($this->manipulator->setParams(['fm' => 'webp'])->run($this->avif)));
- $this->assertSame('image/avif', $this->getMime($this->manipulator->setParams(['fm' => 'avif'])->run($this->webp)));
- }
- }
-
- public function testGetFormat()
- {
- $image = \Mockery::mock(ImageInterface::class, function ($mock) {
- $mock->shouldReceive('origin')->andReturn(\Mockery::mock('Intervention\Image\Origin', ['mediaType' => 'image/jpeg']))->once();
- $mock->shouldReceive('origin')->andReturn(\Mockery::mock('Intervention\Image\Origin', ['mediaType' => 'image/png']))->once();
- $mock->shouldReceive('origin')->andReturn(\Mockery::mock('Intervention\Image\Origin', ['mediaType' => 'image/gif']))->once();
- $mock->shouldReceive('origin')->andReturn(\Mockery::mock('Intervention\Image\Origin', ['mediaType' => 'image/bmp']))->once();
- $mock->shouldReceive('origin')->andReturn(\Mockery::mock('Intervention\Image\Origin', ['mediaType' => 'image/jpeg']))->twice();
-
- if (function_exists('imagecreatefromwebp')) {
- $mock->shouldReceive('origin')->andReturn(\Mockery::mock('Intervention\Image\Origin', ['mediaType' => 'image/webp']))->once();
- }
-
- if (function_exists('imagecreatefromavif')) {
- $mock->shouldReceive('origin')->andReturn(\Mockery::mock('Intervention\Image\Origin', ['mediaType' => 'image/avif']))->once();
- }
- });
-
- $this->assertSame('jpg', $this->manipulator->setParams(['fm' => 'jpg'])->getFormat($image));
- $this->assertSame('png', $this->manipulator->setParams(['fm' => 'png'])->getFormat($image));
- $this->assertSame('gif', $this->manipulator->setParams(['fm' => 'gif'])->getFormat($image));
- $this->assertSame('jpg', $this->manipulator->setParams(['fm' => null])->getFormat($image));
- $this->assertSame('png', $this->manipulator->setParams(['fm' => null])->getFormat($image));
- $this->assertSame('gif', $this->manipulator->setParams(['fm' => null])->getFormat($image));
- $this->assertSame('jpg', $this->manipulator->setParams(['fm' => null])->getFormat($image));
- $this->assertSame('jpg', $this->manipulator->setParams(['fm' => ''])->getFormat($image));
- $this->assertSame('jpg', $this->manipulator->setParams(['fm' => 'invalid'])->getFormat($image));
-
- if (function_exists('imagecreatefromwebp')) {
- $this->assertSame('webp', $this->manipulator->setParams(['fm' => null])->getFormat($image));
- }
-
- if (function_exists('imagecreatefromavif')) {
- $this->assertSame('avif', $this->manipulator->setParams(['fm' => null])->getFormat($image));
- }
- }
-
- public function testGetQuality()
- {
- $this->assertSame(100, $this->manipulator->setParams(['q' => '100'])->getQuality());
- $this->assertSame(100, $this->manipulator->setParams(['q' => 100])->getQuality());
- $this->assertSame(90, $this->manipulator->setParams(['q' => null])->getQuality());
- $this->assertSame(90, $this->manipulator->setParams(['q' => 'a'])->getQuality());
- $this->assertSame(50, $this->manipulator->setParams(['q' => '50.50'])->getQuality());
- $this->assertSame(90, $this->manipulator->setParams(['q' => '-1'])->getQuality());
- $this->assertSame(90, $this->manipulator->setParams(['q' => '101'])->getQuality());
- }
-
- /**
- * Test functions that require the imagick extension.
- *
- * @return void
- */
- public function testWithImagick()
- {
- if (!extension_loaded('imagick')) {
- $this->markTestSkipped(
- 'The imagick extension is not available.'
- );
- }
- $manager = ImageManager::imagick();
- // These need to be recreated with the imagick driver selected in the manager
- $this->jpg = $manager->read($manager->create(100, 100)->encode(new MediaTypeEncoder('image/jpeg'))->toFilePointer());
- $this->png = $manager->read($manager->create(100, 100)->encode(new MediaTypeEncoder('image/png'))->toFilePointer());
- $this->gif = $manager->read($manager->create(100, 100)->encode(new MediaTypeEncoder('image/gif'))->toFilePointer());
- $this->heic = $manager->read($manager->create(100, 100)->encode(new MediaTypeEncoder('image/heic'))->toFilePointer());
- $this->tif = $manager->read($manager->create(100, 100)->encode(new MediaTypeEncoder('image/tiff'))->toFilePointer());
-
- $this->assertSame('image/tiff', $this->getMime($this->manipulator->setParams(['fm' => 'tiff'])->run($this->jpg)));
- $this->assertSame('image/tiff', $this->getMime($this->manipulator->setParams(['fm' => 'tiff'])->run($this->png)));
- $this->assertSame('image/tiff', $this->getMime($this->manipulator->setParams(['fm' => 'tiff'])->run($this->gif)));
- $this->assertSame('image/tiff', $this->getMime($this->manipulator->setParams(['fm' => 'tiff'])->run($this->heic)));
- }
-
- public function testSupportedFormats()
- {
- $expected = [
- 'avif' => 'image/avif',
- 'gif' => 'image/gif',
- 'jpg' => 'image/jpeg',
- 'pjpg' => 'image/jpeg',
- 'png' => 'image/png',
- 'webp' => 'image/webp',
- 'tiff' => 'image/tiff',
- 'heic' => 'image/heic',
- ];
-
- $this->assertSame($expected, Encode::supportedFormats());
- }
-
- protected function getMime(ImageInterface $image)
- {
- return $image->origin()->mediaType();
- }
-}