diff --git a/src/Drivers/Gd/Decoders/NativeObjectDecoder.php b/src/Drivers/Gd/Decoders/NativeObjectDecoder.php index 740e58e7..74c5e9e9 100644 --- a/src/Drivers/Gd/Decoders/NativeObjectDecoder.php +++ b/src/Drivers/Gd/Decoders/NativeObjectDecoder.php @@ -34,17 +34,23 @@ public function decode(mixed $input): ImageInterface|ColorInterface if (!imageistruecolor($input)) { imagepalettetotruecolor($input); + $indexed = true; } imagesavealpha($input, true); // build image instance - return new Image( + $image = new Image( $this->driver(), new Core([ new Frame($input) ]) ); + + // set origin + $image->origin()->setIndexed($indexed ?? false); + + return $image; } /** diff --git a/src/Drivers/Gd/Encoders/PngEncoder.php b/src/Drivers/Gd/Encoders/PngEncoder.php index 6b20ea91..a333424f 100644 --- a/src/Drivers/Gd/Encoders/PngEncoder.php +++ b/src/Drivers/Gd/Encoders/PngEncoder.php @@ -6,6 +6,7 @@ use Intervention\Image\EncodedImage; use Intervention\Image\Encoders\PngEncoder as GenericPngEncoder; +use Intervention\Image\Exceptions\RuntimeException; use Intervention\Image\Interfaces\ImageInterface; use Intervention\Image\Interfaces\SpecializedInterface; @@ -13,13 +14,35 @@ class PngEncoder extends GenericPngEncoder implements SpecializedInterface { public function encode(ImageInterface $image): EncodedImage { - $gd = $image->core()->native(); + $gd = $this->maybeToPalette(clone $image) + ->core() + ->native(); + $data = $this->buffered(function () use ($gd) { imageinterlace($gd, $this->interlaced); imagepng($gd, null, -1); - imageinterlace($gd, false); }); return new EncodedImage($data, 'image/png'); } + + /** + * Maybe turn given image color to indexed palette version according to encoder settings + * + * @param ImageInterface $image + * @throws RuntimeException + * @return ImageInterface + */ + private function maybeToPalette(ImageInterface $image): ImageInterface + { + if ($this->indexed === false) { + return $image; + } + + if (is_null($this->indexed) && !$image->origin()->indexed()) { + return $image; + } + + return $image->reduceColors(255); + } } diff --git a/src/Drivers/Imagick/Decoders/NativeObjectDecoder.php b/src/Drivers/Imagick/Decoders/NativeObjectDecoder.php index 3f23902d..3fd86f59 100644 --- a/src/Drivers/Imagick/Decoders/NativeObjectDecoder.php +++ b/src/Drivers/Imagick/Decoders/NativeObjectDecoder.php @@ -27,6 +27,9 @@ public function decode(mixed $input): ImageInterface|ColorInterface throw new DecoderException('Unable to decode input'); } + // get original indexed palette status for origin before any operation + $indexed = $this->hasIndexedColors($input); + // For some JPEG formats, the "coalesceImages()" call leads to an image // completely filled with background color. The logic behind this is // incomprehensible for me; could be an imagick bug. @@ -50,9 +53,43 @@ public function decode(mixed $input): ImageInterface|ColorInterface $image->modify(new AlignRotationModifier()); } - // set media type on origin + // set values on origin $image->origin()->setMediaType($input->getImageMimeType()); + $image->origin()->setIndexed($indexed); return $image; } + + /** + * Determine if given imagick instance is a indexed palette color image + * + * @param Imagick $imagick + * @return bool + */ + private function hasIndexedColors(Imagick $imagick): bool + { + // Palette PNG files with alpha channel result incorrectly in "truecolor with alpha" + // in imagemagick 6 making it impossible to rely on Imagick::getImageType(). + // This workaround looks at the the PNG data directly to decode the color type byte. + + // detect imagick major version + $imagickVersion = dechex(Imagick::getVersion()['versionNumber']); + $imagickVersion = substr($imagickVersion, 0, 1); + + // detect palette status manually in imagemagick 6 + if (version_compare($imagickVersion, '6', '<=') && $imagick->getImageFormat() === 'PNG') { + $data = $imagick->getImageBlob(); + $pos = strpos($data, 'IHDR'); + $type = substr($data, $pos + 13, 1); + $type = unpack('C', $type)[1]; + + return $type === 3; // color type 3 is a PNG with indexed palette + } + + // non-workaround version + return in_array( + $imagick->getImageType(), + [Imagick::IMGTYPE_PALETTE, Imagick::IMGTYPE_PALETTEMATTE], + ); + } } diff --git a/src/Drivers/Imagick/Driver.php b/src/Drivers/Imagick/Driver.php index 88f1d90c..89b769c8 100644 --- a/src/Drivers/Imagick/Driver.php +++ b/src/Drivers/Imagick/Driver.php @@ -57,12 +57,14 @@ public function createImage(int $width, int $height): ImageInterface $background = new ImagickPixel('rgba(255, 255, 255, 0)'); $imagick = new Imagick(); - $imagick->newImage($width, $height, $background, 'png'); + $imagick->newImage($width, $height, $background); $imagick->setType(Imagick::IMGTYPE_UNDEFINED); $imagick->setImageType(Imagick::IMGTYPE_UNDEFINED); $imagick->setColorspace(Imagick::COLORSPACE_SRGB); $imagick->setImageResolution(96, 96); $imagick->setImageBackgroundColor($background); + $imagick->setFormat('PNG32'); + $imagick->setImageFormat('PNG32'); return new Image($this, new Core($imagick)); } diff --git a/src/Drivers/Imagick/Encoders/BmpEncoder.php b/src/Drivers/Imagick/Encoders/BmpEncoder.php index 293767de..c5876228 100644 --- a/src/Drivers/Imagick/Encoders/BmpEncoder.php +++ b/src/Drivers/Imagick/Encoders/BmpEncoder.php @@ -14,7 +14,7 @@ class BmpEncoder extends GenericBmpEncoder implements SpecializedInterface { public function encode(ImageInterface $image): EncodedImage { - $format = 'bmp'; + $format = 'BMP'; $compression = Imagick::COMPRESSION_NO; $imagick = $image->core()->native(); diff --git a/src/Drivers/Imagick/Encoders/GifEncoder.php b/src/Drivers/Imagick/Encoders/GifEncoder.php index 41783a39..3670fdc6 100644 --- a/src/Drivers/Imagick/Encoders/GifEncoder.php +++ b/src/Drivers/Imagick/Encoders/GifEncoder.php @@ -14,7 +14,7 @@ class GifEncoder extends GenericGifEncoder implements SpecializedInterface { public function encode(ImageInterface $image): EncodedImage { - $format = 'gif'; + $format = 'GIF'; $compression = Imagick::COMPRESSION_LZW; $imagick = $image->core()->native(); diff --git a/src/Drivers/Imagick/Encoders/Jpeg2000Encoder.php b/src/Drivers/Imagick/Encoders/Jpeg2000Encoder.php index db0cc13a..5c4bd59e 100644 --- a/src/Drivers/Imagick/Encoders/Jpeg2000Encoder.php +++ b/src/Drivers/Imagick/Encoders/Jpeg2000Encoder.php @@ -15,7 +15,7 @@ class Jpeg2000Encoder extends GenericJpeg2000Encoder implements SpecializedInter { public function encode(ImageInterface $image): EncodedImageInterface { - $format = 'jp2'; + $format = 'JP2'; $compression = Imagick::COMPRESSION_JPEG; $imagick = $image->core()->native(); diff --git a/src/Drivers/Imagick/Encoders/JpegEncoder.php b/src/Drivers/Imagick/Encoders/JpegEncoder.php index 9484f3ca..7772d88e 100644 --- a/src/Drivers/Imagick/Encoders/JpegEncoder.php +++ b/src/Drivers/Imagick/Encoders/JpegEncoder.php @@ -14,7 +14,7 @@ class JpegEncoder extends GenericJpegEncoder implements SpecializedInterface { public function encode(ImageInterface $image): EncodedImage { - $format = 'jpeg'; + $format = 'JPEG'; $compression = Imagick::COMPRESSION_JPEG; $blendingColor = $this->driver()->handleInput( $this->driver()->config()->blendingColor diff --git a/src/Drivers/Imagick/Encoders/PngEncoder.php b/src/Drivers/Imagick/Encoders/PngEncoder.php index b6614ba1..088c37ba 100644 --- a/src/Drivers/Imagick/Encoders/PngEncoder.php +++ b/src/Drivers/Imagick/Encoders/PngEncoder.php @@ -5,28 +5,88 @@ namespace Intervention\Image\Drivers\Imagick\Encoders; use Imagick; +use ImagickException; use Intervention\Image\EncodedImage; use Intervention\Image\Encoders\PngEncoder as GenericPngEncoder; use Intervention\Image\Interfaces\ImageInterface; use Intervention\Image\Interfaces\SpecializedInterface; +use Intervention\Image\Origin; class PngEncoder extends GenericPngEncoder implements SpecializedInterface { public function encode(ImageInterface $image): EncodedImage { - $format = 'png'; - $compression = Imagick::COMPRESSION_ZIP; + $imagick = clone $image->core()->native(); + $imagick->setCompression(Imagick::COMPRESSION_ZIP); + $imagick->setImageCompression(Imagick::COMPRESSION_ZIP); - $imagick = $image->core()->native(); - $imagick->setFormat($format); - $imagick->setImageFormat($format); - $imagick->setCompression($compression); - $imagick->setImageCompression($compression); + $imagick = $this->setInterlaced($imagick); + $imagick = $this->setIndexed($imagick, $image->origin()); - if ($this->interlaced) { - $imagick->setInterlaceScheme(Imagick::INTERLACE_LINE); + return new EncodedImage($imagick->getImagesBlob(), 'image/png'); + } + + /** + * Set interlace mode on given imagick object according to encoder settings + * + * @param Imagick $imagick + * @return Imagick + * @throws ImagickException + */ + private function setInterlaced(Imagick $imagick): Imagick + { + switch ($this->interlaced) { + case true: + $imagick->setInterlaceScheme(Imagick::INTERLACE_LINE); + break; + + case false: + $imagick->setInterlaceScheme(Imagick::INTERLACE_NO); + break; } - return new EncodedImage($imagick->getImagesBlob(), 'image/png'); + return $imagick; + } + + /** + * Set indexed color mode on given imagick object according to encoder settings + * + * @param Imagick $imagick + * @return Imagick + */ + private function setIndexed(Imagick $imagick, Origin $origin): Imagick + { + if ($this->indexed === true) { + $imagick->setFormat('PNG8'); + $imagick->setImageFormat('PNG8'); + $imagick->quantizeImage( + 256, + $imagick->getImageColorspace(), + 0, + false, + false + ); + } elseif ($this->indexed === false) { + $imagick->setFormat('PNG32'); + $imagick->setImageFormat('PNG32'); + } elseif ($origin->indexed() === true) { + $imagick->setFormat('PNG8'); + $imagick->setImageFormat('PNG8'); + $imagick->quantizeImage( + 256, + $imagick->getImageColorspace(), + 0, + false, + false + ); + } elseif ($origin->indexed() === false) { + $imagick->setFormat('PNG32'); + $imagick->setImageFormat('PNG32'); + } else { + $imagick->setFormat('PNG'); + $imagick->setImageFormat('PNG'); + } + + return $imagick; } } diff --git a/src/Drivers/Imagick/Encoders/WebpEncoder.php b/src/Drivers/Imagick/Encoders/WebpEncoder.php index 93a26fd9..8b19f2ac 100644 --- a/src/Drivers/Imagick/Encoders/WebpEncoder.php +++ b/src/Drivers/Imagick/Encoders/WebpEncoder.php @@ -15,7 +15,7 @@ class WebpEncoder extends GenericWebpEncoder implements SpecializedInterface { public function encode(ImageInterface $image): EncodedImage { - $format = 'webp'; + $format = 'WEBP'; $compression = Imagick::COMPRESSION_ZIP; $imagick = $image->core()->native(); diff --git a/src/Encoders/PngEncoder.php b/src/Encoders/PngEncoder.php index b6bb6cb5..a04b8e0c 100644 --- a/src/Encoders/PngEncoder.php +++ b/src/Encoders/PngEncoder.php @@ -8,7 +8,7 @@ class PngEncoder extends SpecializableEncoder { - public function __construct(public bool $interlaced = false) + public function __construct(public ?bool $interlaced = null, public ?bool $indexed = null) { } } diff --git a/src/Origin.php b/src/Origin.php index 4cd7a8e4..e1af0572 100644 --- a/src/Origin.php +++ b/src/Origin.php @@ -6,6 +6,8 @@ class Origin { + protected bool $indexed = false; + /** * Create new origin instance * @@ -85,4 +87,27 @@ public function fileExtension(): ?string { return empty($this->filePath) ? null : pathinfo($this->filePath, PATHINFO_EXTENSION); } + + /** + * Get the marker that indicates whether the origin contains an indexed color palette + * + * @return bool + */ + public function indexed(): bool + { + return $this->indexed; + } + + /** + * Set the marker that indicates whether the origin contains an indexed color palette + * + * @param bool $status + * @return Origin + */ + public function setIndexed(bool $status): self + { + $this->indexed = $status; + + return $this; + } } diff --git a/tests/GdTestCase.php b/tests/GdTestCase.php index 2cfa9527..4016bf3e 100644 --- a/tests/GdTestCase.php +++ b/tests/GdTestCase.php @@ -12,14 +12,14 @@ abstract class GdTestCase extends BaseTestCase { - public function readTestImage($filename = 'test.jpg'): Image + public static function readTestImage($filename = 'test.jpg'): Image { return (new Driver())->specialize(new FilePathImageDecoder())->decode( - $this->getTestResourcePath($filename) + static::getTestResourcePath($filename) ); } - public function createTestImage(int $width, int $height): Image + public static function createTestImage(int $width, int $height): Image { $gd = imagecreatetruecolor($width, $height); imagefill($gd, 0, 0, imagecolorallocate($gd, 255, 0, 0)); @@ -32,7 +32,24 @@ public function createTestImage(int $width, int $height): Image ); } - public function createTestAnimation(): Image + public static function createTestImageTransparent(int $width, int $height): Image + { + $gd = imagecreatetruecolor($width, $height); + imagesavealpha($gd, true); + $background = imagecolorallocatealpha($gd, 255, 255, 255, 127); + imagealphablending($gd, false); + imagefill($gd, 0, 0, $background); + imagecolortransparent($gd, $background); + + return new Image( + new Driver(), + new Core([ + new Frame($gd) + ]) + ); + } + + public static function createTestAnimation(): Image { $gd1 = imagecreatetruecolor(3, 2); imagefill($gd1, 0, 0, imagecolorallocate($gd1, 255, 0, 0)); diff --git a/tests/ImagickTestCase.php b/tests/ImagickTestCase.php index cbd24dcc..437000ae 100644 --- a/tests/ImagickTestCase.php +++ b/tests/ImagickTestCase.php @@ -13,22 +13,24 @@ abstract class ImagickTestCase extends BaseTestCase { - public function readTestImage($filename = 'test.jpg'): Image + public static function readTestImage($filename = 'test.jpg'): Image { return (new Driver())->specialize(new FilePathImageDecoder())->decode( - $this->getTestResourcePath($filename) + static::getTestResourcePath($filename) ); } - public function createTestImage(int $width, int $height): Image + public static function createTestImage(int $width, int $height): Image { $background = new ImagickPixel('rgb(255, 0, 0)'); $imagick = new Imagick(); - $imagick->newImage($width, $height, $background, 'png'); + $imagick->newImage($width, $height, $background); $imagick->setType(Imagick::IMGTYPE_UNDEFINED); $imagick->setImageType(Imagick::IMGTYPE_UNDEFINED); $imagick->setColorspace(Imagick::COLORSPACE_SRGB); $imagick->setImageResolution(96, 96); + $imagick->setFormat('PNG32'); + $imagick->setImageFormat('PNG32'); return new Image( new Driver(), @@ -36,7 +38,26 @@ public function createTestImage(int $width, int $height): Image ); } - public function createTestAnimation(): Image + public static function createTestImageTransparent(int $width, int $height): Image + { + $background = new ImagickPixel('rgba(255, 255, 255, 0)'); + $imagick = new Imagick(); + $imagick->newImage($width, $height, $background); + $imagick->setType(Imagick::IMGTYPE_UNDEFINED); + $imagick->setImageType(Imagick::IMGTYPE_UNDEFINED); + $imagick->setColorspace(Imagick::COLORSPACE_SRGB); + $imagick->setImageResolution(96, 96); + $imagick->setImageBackgroundColor($background); + $imagick->setFormat('PNG32'); + $imagick->setImageFormat('PNG32'); + + return new Image( + new Driver(), + new Core($imagick) + ); + } + + public static function createTestAnimation(): Image { $imagick = new Imagick(); $imagick->setFormat('gif'); diff --git a/tests/Traits/CanDetectInterlacedPng.php b/tests/Traits/CanDetectInterlacedPng.php deleted file mode 100644 index 19fffe46..00000000 --- a/tests/Traits/CanDetectInterlacedPng.php +++ /dev/null @@ -1,27 +0,0 @@ -buildFilePointer($imagedata); - $contents = fread($f, 32); - fclose($f); - - return ord($contents[28]) != 0; - } -} diff --git a/tests/Traits/CanInspectPng.php b/tests/Traits/CanInspectPng.php new file mode 100644 index 00000000..e3f13991 --- /dev/null +++ b/tests/Traits/CanInspectPng.php @@ -0,0 +1,52 @@ +buildFilePointer($imagedata); + $contents = fread($f, 32); + fclose($f); + + return ord($contents[28]) != 0; + } + + /** + * Try to detect PNG color type from given binary data + * + * @param string $data + * @return string + */ + private function pngColorType(string $data): string + { + if (substr($data, 1, 3) !== 'PNG') { + return 'unkown'; + } + + $pos = strpos($data, 'IHDR'); + $type = substr($data, $pos + 13, 1); + + return match (unpack('C', $type)[1]) { + 0 => 'grayscale', + 2 => 'truecolor', + 3 => 'indexed', + 4 => 'grayscale-alpha', + 6 => 'truecolor-alpha', + default => 'unknown', + }; + } +} diff --git a/tests/Unit/Drivers/Gd/Encoders/PngEncoderTest.php b/tests/Unit/Drivers/Gd/Encoders/PngEncoderTest.php index 9c96591a..b8485ca7 100644 --- a/tests/Unit/Drivers/Gd/Encoders/PngEncoderTest.php +++ b/tests/Unit/Drivers/Gd/Encoders/PngEncoderTest.php @@ -7,15 +7,17 @@ use PHPUnit\Framework\Attributes\CoversClass; use PHPUnit\Framework\Attributes\RequiresPhpExtension; use Intervention\Image\Encoders\PngEncoder; +use Intervention\Image\Interfaces\ImageInterface; use Intervention\Image\Tests\GdTestCase; -use Intervention\Image\Tests\Traits\CanDetectInterlacedPng; +use Intervention\Image\Tests\Traits\CanInspectPng; +use PHPUnit\Framework\Attributes\DataProvider; #[RequiresPhpExtension('gd')] #[CoversClass(\Intervention\Image\Encoders\PngEncoder::class)] #[CoversClass(\Intervention\Image\Drivers\Gd\Encoders\PngEncoder::class)] final class PngEncoderTest extends GdTestCase { - use CanDetectInterlacedPng; + use CanInspectPng; public function testEncode(): void { @@ -34,4 +36,94 @@ public function testEncodeInterlaced(): void $this->assertMediaType('image/png', (string) $result); $this->assertTrue($this->isInterlacedPng((string) $result)); } + + #[DataProvider('indexedDataProvider')] + public function testEncoderIndexed(ImageInterface $image, PngEncoder $encoder, string $result): void + { + $this->assertEquals( + $result, + $this->pngColorType((string) $encoder->encode($image)), + ); + } + + public static function indexedDataProvider(): array + { + return [ + [ + static::createTestImage(3, 2), // truecolor-alpha + new PngEncoder(), + 'truecolor-alpha', + ], + [ + static::createTestImage(3, 2), // truecolor-alpha + new PngEncoder(indexed: true), + 'indexed', + ], + [ + static::createTestImage(3, 2), // truecolor-alpha + new PngEncoder(indexed: false), + 'truecolor-alpha', + ], + [ + static::createTestImageTransparent(3, 2), // truecolor-alpha + new PngEncoder(), + 'truecolor-alpha', + ], + [ + static::createTestImageTransparent(3, 2), // truecolor-alpha + new PngEncoder(indexed: true), + 'indexed', + ], + [ + static::createTestImageTransparent(3, 2), // truecolor-alpha + new PngEncoder(indexed: false), + 'truecolor-alpha', + ], + [ + static::createTestImageTransparent(3, 2)->fill('fff'), // truecolor-alpha + new PngEncoder(), + 'truecolor-alpha', + ], + [ + static::createTestImageTransparent(3, 2)->fill('fff'), // truecolor-alpha + new PngEncoder(indexed: true), + 'indexed', + ], + [ + static::createTestImageTransparent(3, 2)->fill('fff'), // truecolor-alpha + new PngEncoder(indexed: false), + 'truecolor-alpha', + ], + [ + static::readTestImage('tile.png'), // indexed + new PngEncoder(), + 'indexed', + ], + [ + static::readTestImage('tile.png'), // indexed + new PngEncoder(indexed: true), + 'indexed', + ], + [ + static::readTestImage('tile.png'), // indexed + new PngEncoder(indexed: false), + 'truecolor-alpha', + ], + [ + static::readTestImage('test.jpg'), // foreign format + new PngEncoder(), + 'truecolor-alpha', + ], + [ + static::readTestImage('test.jpg'), // foreign format + new PngEncoder(indexed: true), + 'indexed', + ], + [ + static::readTestImage('test.jpg'), // foreign format + new PngEncoder(indexed: false), + 'truecolor-alpha', + ] + ]; + } } diff --git a/tests/Unit/Drivers/Imagick/Encoders/PngEncoderTest.php b/tests/Unit/Drivers/Imagick/Encoders/PngEncoderTest.php index 503320b7..15b599e5 100644 --- a/tests/Unit/Drivers/Imagick/Encoders/PngEncoderTest.php +++ b/tests/Unit/Drivers/Imagick/Encoders/PngEncoderTest.php @@ -7,15 +7,17 @@ use PHPUnit\Framework\Attributes\CoversClass; use PHPUnit\Framework\Attributes\RequiresPhpExtension; use Intervention\Image\Encoders\PngEncoder; +use Intervention\Image\Interfaces\ImageInterface; use Intervention\Image\Tests\ImagickTestCase; -use Intervention\Image\Tests\Traits\CanDetectInterlacedPng; +use Intervention\Image\Tests\Traits\CanInspectPng; +use PHPUnit\Framework\Attributes\DataProvider; #[RequiresPhpExtension('imagick')] #[CoversClass(\Intervention\Image\Encoders\PngEncoder::class)] #[CoversClass(\Intervention\Image\Drivers\Imagick\Encoders\PngEncoder::class)] final class PngEncoderTest extends ImagickTestCase { - use CanDetectInterlacedPng; + use CanInspectPng; public function testEncode(): void { @@ -34,4 +36,94 @@ public function testEncodeInterlaced(): void $this->assertMediaType('image/png', (string) $result); $this->assertTrue($this->isInterlacedPng((string) $result)); } + + #[DataProvider('indexedDataProvider')] + public function testEncoderIndexed(ImageInterface $image, PngEncoder $encoder, string $result): void + { + $this->assertEquals( + $result, + $this->pngColorType((string) $encoder->encode($image)), + ); + } + + public static function indexedDataProvider(): array + { + return [ + [ + static::createTestImage(3, 2), // truecolor-alpha + new PngEncoder(), + 'truecolor-alpha', + ], + [ + static::createTestImage(3, 2), // truecolor-alpha + new PngEncoder(indexed: true), + 'indexed', + ], + [ + static::createTestImage(3, 2), // truecolor-alpha + new PngEncoder(indexed: false), + 'truecolor-alpha', + ], + [ + static::createTestImageTransparent(3, 2), // truecolor-alpha + new PngEncoder(), + 'truecolor-alpha', + ], + [ + static::createTestImageTransparent(3, 2), // truecolor-alpha + new PngEncoder(indexed: true), + 'indexed', + ], + [ + static::createTestImageTransparent(3, 2), // truecolor-alpha + new PngEncoder(indexed: false), + 'truecolor-alpha', + ], + [ + static::createTestImageTransparent(3, 2)->fill('fff'), // truecolor-alpha + new PngEncoder(), + 'truecolor-alpha', + ], + [ + static::createTestImageTransparent(3, 2)->fill('fff'), // truecolor-alpha + new PngEncoder(indexed: true), + 'indexed', + ], + [ + static::createTestImageTransparent(3, 2)->fill('fff'), // truecolor-alpha + new PngEncoder(indexed: false), + 'truecolor-alpha', + ], + [ + static::readTestImage('tile.png'), // indexed + new PngEncoder(), + 'indexed', + ], + [ + static::readTestImage('tile.png'), // indexed + new PngEncoder(indexed: true), + 'indexed', + ], + [ + static::readTestImage('tile.png'), // indexed + new PngEncoder(indexed: false), + 'truecolor-alpha', + ], + [ + static::readTestImage('test.jpg'), // foreign format + new PngEncoder(), + 'truecolor-alpha', + ], + [ + static::readTestImage('test.jpg'), // foreign format + new PngEncoder(indexed: true), + 'indexed', + ], + [ + static::readTestImage('test.jpg'), // foreign format + new PngEncoder(indexed: false), + 'truecolor-alpha', + ] + ]; + } } diff --git a/tests/Unit/OriginTest.php b/tests/Unit/OriginTest.php index 2932ed48..64909183 100644 --- a/tests/Unit/OriginTest.php +++ b/tests/Unit/OriginTest.php @@ -36,4 +36,14 @@ public function testSetGetMediaType(): void $this->assertEquals('image/jpeg', $origin->mediaType()); $this->assertEquals('image/jpeg', $result->mediaType()); } + + public function testSetGetIndexed(): void + { + $origin = new Origin(); + $this->assertFalse($origin->indexed()); + + $origin = new Origin(); + $origin->setIndexed(true); + $this->assertTrue($origin->indexed()); + } }