diff --git a/src/Imagick/Image.php b/src/Imagick/Image.php index 9e62fcb2b..cf5084973 100644 --- a/src/Imagick/Image.php +++ b/src/Imagick/Image.php @@ -830,6 +830,22 @@ private function applyImageOptions(\Imagick $image, array $options, $path) $image->setOption('webp:lossless', $options['webp_lossless']); } break; + case 'jxl': + if (!isset($options[$format . '_quality'])) { + if (isset($options['quality'])) { + $options[$format . '_quality'] = $options['quality']; + } + } + if (isset($options[$format . '_quality'])) { + $options[$format . '_quality'] = max(9, min(99, $options[$format . '_quality'])); + $image->setimagecompressionquality($options[$format . '_quality']); + $image->setcompressionquality($options[$format . '_quality']); + } + if (!empty($options[$format . '_lossless'])) { + $image->setimagecompressionquality(100); + $image->setcompressionquality(100); + } + break; } if (isset($options['resolution-units']) && isset($options['resolution-x']) && isset($options['resolution-y'])) { if (empty($options['resampling-filter'])) { @@ -935,6 +951,7 @@ private function getMimeType($format) static $mimeTypes = array( 'jpeg' => 'image/jpeg', 'jpg' => 'image/jpeg', + 'jxl' => 'image/jxl', 'gif' => 'image/gif', 'png' => 'image/png', 'wbmp' => 'image/vnd.wap.wbmp', diff --git a/tests/fixtures/jxl-image.jxl b/tests/fixtures/jxl-image.jxl new file mode 100644 index 000000000..dd86e6850 Binary files /dev/null and b/tests/fixtures/jxl-image.jxl differ diff --git a/tests/tests/Gd/ImageTest.php b/tests/tests/Gd/ImageTest.php index be6810fdd..70b6603b2 100644 --- a/tests/tests/Gd/ImageTest.php +++ b/tests/tests/Gd/ImageTest.php @@ -193,6 +193,9 @@ public function testSaveCompressionQuality($format, array $smallSizeOptions, arr if ($format === 'webp' && !function_exists('imagewebp')) { $this->markTestSkipped('GD webp support is not enabled'); } + if ($format === 'jxl') { + $this->markTestSkipped('GD does not support ' . strtoupper($format)); + } return parent::testSaveCompressionQuality($format, $smallSizeOptions, $bigSizeOptions); } diff --git a/tests/tests/Gd/ImagineTest.php b/tests/tests/Gd/ImagineTest.php index 94b226614..d13984a60 100644 --- a/tests/tests/Gd/ImagineTest.php +++ b/tests/tests/Gd/ImagineTest.php @@ -47,6 +47,16 @@ public function testShouldOpenAWebPImage() return parent::testShouldOpenAWebPImage(); } + /** + * {@inheritdoc} + * + * @see \Imagine\Test\Image\AbstractImagineTest::testShouldOpenAJxlImage() + */ + public function testShouldOpenAJxlImage() + { + $this->markTestSkipped('GD does not support JXL'); + } + /** * {@inheritdoc} * diff --git a/tests/tests/Gmagick/ImageTest.php b/tests/tests/Gmagick/ImageTest.php index 80e1cd92f..20326a340 100644 --- a/tests/tests/Gmagick/ImageTest.php +++ b/tests/tests/Gmagick/ImageTest.php @@ -145,8 +145,8 @@ public function pasteWithAlphaProvider() public function testSaveCompressionQuality($format, array $smallSizeOptions, array $bigSizeOptions) { $gmagick = new \Gmagick(); - if ($format === 'webp' && !in_array('WEBP', $gmagick->queryformats('WEBP'), true)) { - $this->markTestSkipped('Gmagick webp support is not enabled'); + if (in_array($format, array('webp', 'jxl'), true) && !in_array(strtoupper($format), $gmagick->queryformats(strtoupper($format)), true)) { + $this->markTestSkipped('Gmagick ' . $format . ' support is not enabled'); } return parent::testSaveCompressionQuality($format, $smallSizeOptions, $bigSizeOptions); diff --git a/tests/tests/Gmagick/ImagineTest.php b/tests/tests/Gmagick/ImagineTest.php index b7c6ac8ac..d87f665f1 100644 --- a/tests/tests/Gmagick/ImagineTest.php +++ b/tests/tests/Gmagick/ImagineTest.php @@ -60,6 +60,21 @@ public function testShouldOpenAWebPImage() return parent::testShouldOpenAWebPImage(); } + /** + * {@inheritdoc} + * + * @see \Imagine\Test\Image\AbstractImagineTest::testShouldOpenAJxlImage() + */ + public function testShouldOpenAJxlImage() + { + $gmagick = new \Gmagick(); + if (!in_array('JXL', $gmagick->queryformats('JXL'), true)) { + $this->markTestSkipped('Gmagick JXL support is not enabled'); + } + + return parent::testShouldOpenAJxlImage(); + } + /** * {@inheritdoc} * diff --git a/tests/tests/Image/AbstractImageTest.php b/tests/tests/Image/AbstractImageTest.php index 46e7f0899..a06c2e260 100644 --- a/tests/tests/Image/AbstractImageTest.php +++ b/tests/tests/Image/AbstractImageTest.php @@ -981,6 +981,8 @@ public function imageCompressionQualityProvider() array('jpg', array('jpeg_quality' => 0), array('jpeg_quality' => 100)), array('png', array('png_compression_level' => 9), array('png_compression_level' => 0)), array('webp', array('webp_quality' => 0), array('webp_quality' => 100)), + array('jxl', array('jxl_quality' => 0), array('jxl_quality' => 100)), + array('jxl', array('jxl_quality' => 0), array('jxl_lossless' => true)), ); } diff --git a/tests/tests/Image/AbstractImagineTest.php b/tests/tests/Image/AbstractImagineTest.php index eae285ff4..8141cea67 100644 --- a/tests/tests/Image/AbstractImagineTest.php +++ b/tests/tests/Image/AbstractImagineTest.php @@ -61,6 +61,20 @@ public function testShouldOpenAWebPImage() $this->assertEquals(realpath($source), $metadata['filepath']); } + public function testShouldOpenAJxlImage() + { + $source = IMAGINE_TEST_FIXTURESFOLDER . '/jxl-image.jxl'; + $factory = $this->getImagine(); + $image = $factory->open($source); + $size = $image->getSize(); + $this->assertInstanceOf('Imagine\Image\ImageInterface', $image); + $this->assertEquals(100, $size->getWidth()); + $this->assertEquals(100, $size->getHeight()); + $metadata = $image->metadata(); + $this->assertEquals($source, $metadata['uri']); + $this->assertEquals(realpath($source), $metadata['filepath']); + } + public function testShouldOpenAnSplFileResource() { $source = IMAGINE_TEST_FIXTURESFOLDER . '/google.png'; diff --git a/tests/tests/Imagick/ImageTest.php b/tests/tests/Imagick/ImageTest.php index ab1cb6ed6..8cf8b9965 100644 --- a/tests/tests/Imagick/ImageTest.php +++ b/tests/tests/Imagick/ImageTest.php @@ -172,8 +172,8 @@ public function testOptimize() */ public function testSaveCompressionQuality($format, array $smallSizeOptions, array $bigSizeOptions) { - if ($format === 'webp' && !in_array('WEBP', \Imagick::queryFormats('WEBP'), true)) { - $this->markTestSkipped('Imagick WebP support is not enabled'); + if (in_array($format, array('webp', 'jxl'), true) && !in_array(strtoupper($format), \Imagick::queryFormats(strtoupper($format)), true)) { + $this->markTestSkipped('Imagick ' . $format . ' support is not enabled'); } return parent::testSaveCompressionQuality($format, $smallSizeOptions, $bigSizeOptions); diff --git a/tests/tests/Imagick/ImagineTest.php b/tests/tests/Imagick/ImagineTest.php index d1a68e385..117752dd3 100644 --- a/tests/tests/Imagick/ImagineTest.php +++ b/tests/tests/Imagick/ImagineTest.php @@ -47,6 +47,20 @@ public function testShouldOpenAWebPImage() return parent::testShouldOpenAWebPImage(); } + /** + * {@inheritdoc} + * + * @see \Imagine\Test\Image\AbstractImagineTest::testShouldOpenAJxlImage() + */ + public function testShouldOpenAJxlImage() + { + if (!in_array('JXL', \Imagick::queryFormats('JXL'), true)) { + $this->markTestSkipped('Imagick JXL support is not enabled'); + } + + return parent::testShouldOpenAJxlImage(); + } + /** * {@inheritdoc} *