From ba9272b9e8e44efc2dd1391e4c50b12073f69dbb Mon Sep 17 00:00:00 2001 From: Oliver Vogel Date: Tue, 31 Oct 2023 11:31:47 +0100 Subject: [PATCH] Implement color limit for Bitmap encoders --- src/Drivers/Abstract/AbstractImage.php | 8 ++++---- src/Drivers/Gd/Encoders/BmpEncoder.php | 13 +++++++++++-- src/Drivers/Imagick/Encoders/BmpEncoder.php | 9 +++++++++ src/Interfaces/ImageInterface.php | 7 +++++++ tests/Drivers/Gd/Encoders/BmpEncoderTest.php | 4 ++-- .../Drivers/Imagick/Encoders/BmpEncoderTest.php | 15 +++++++++++++++ tests/images/gradient.bmp | Bin 0 -> 152 bytes 7 files changed, 48 insertions(+), 8 deletions(-) create mode 100644 tests/images/gradient.bmp diff --git a/src/Drivers/Abstract/AbstractImage.php b/src/Drivers/Abstract/AbstractImage.php index ca4d2f74b..ead5f73d2 100644 --- a/src/Drivers/Abstract/AbstractImage.php +++ b/src/Drivers/Abstract/AbstractImage.php @@ -84,16 +84,16 @@ public function toPng(int $color_limit = 0): EncodedImage ); } - public function toBitmap(): EncodedImage + public function toBitmap(int $color_limit = 0): EncodedImage { return $this->encode( - $this->resolveDriverClass('Encoders\BmpEncoder') + $this->resolveDriverClass('Encoders\BmpEncoder', $color_limit) ); } - public function toBmp(): EncodedImage + public function toBmp(int $color_limit = 0): EncodedImage { - return $this->toBitmap(); + return $this->toBitmap($color_limit); } public function toAvif(): EncodedImage diff --git a/src/Drivers/Gd/Encoders/BmpEncoder.php b/src/Drivers/Gd/Encoders/BmpEncoder.php index 307cf03d5..326987a06 100644 --- a/src/Drivers/Gd/Encoders/BmpEncoder.php +++ b/src/Drivers/Gd/Encoders/BmpEncoder.php @@ -3,16 +3,25 @@ namespace Intervention\Image\Drivers\Gd\Encoders; use Intervention\Image\Drivers\Abstract\Encoders\AbstractEncoder; +use Intervention\Image\Drivers\Gd\Traits\CanReduceColors; use Intervention\Image\EncodedImage; use Intervention\Image\Interfaces\EncoderInterface; use Intervention\Image\Interfaces\ImageInterface; class BmpEncoder extends AbstractEncoder implements EncoderInterface { + use CanReduceColors; + + public function __construct(protected int $color_limit = 0) + { + // + } + public function encode(ImageInterface $image): EncodedImage { - $data = $this->getBuffered(function () use ($image) { - imagebmp($image->frame()->core(), null, false); + $gd = $this->maybeReduceColors($image->frame()->core(), $this->color_limit); + $data = $this->getBuffered(function () use ($gd) { + imagebmp($gd, null, false); }); return new EncodedImage($data, 'image/bmp'); diff --git a/src/Drivers/Imagick/Encoders/BmpEncoder.php b/src/Drivers/Imagick/Encoders/BmpEncoder.php index fd6002c9a..79767f4d9 100644 --- a/src/Drivers/Imagick/Encoders/BmpEncoder.php +++ b/src/Drivers/Imagick/Encoders/BmpEncoder.php @@ -4,12 +4,20 @@ use Imagick; use Intervention\Image\Drivers\Abstract\Encoders\AbstractEncoder; +use Intervention\Image\Drivers\Imagick\Traits\CanReduceColors; use Intervention\Image\EncodedImage; use Intervention\Image\Interfaces\EncoderInterface; use Intervention\Image\Interfaces\ImageInterface; class BmpEncoder extends AbstractEncoder implements EncoderInterface { + use CanReduceColors; + + public function __construct(protected int $color_limit = 0) + { + // + } + public function encode(ImageInterface $image): EncodedImage { $format = 'bmp'; @@ -20,6 +28,7 @@ public function encode(ImageInterface $image): EncodedImage $imagick->setImageFormat($format); $imagick->setCompression($compression); $imagick->setImageCompression($compression); + $this->maybeReduceColors($imagick, $this->color_limit); return new EncodedImage($imagick->getImagesBlob(), 'image/bmp'); } diff --git a/src/Interfaces/ImageInterface.php b/src/Interfaces/ImageInterface.php index c5c5ca90f..8e92e5e4d 100644 --- a/src/Interfaces/ImageInterface.php +++ b/src/Interfaces/ImageInterface.php @@ -137,6 +137,13 @@ public function toAvif(): EncodedImage; */ public function toPng(int $color_limit = 0): EncodedImage; + /** + * Encode image to Windows Bitmap + * + * @return EncodedImage + */ + public function toBitmap(int $color_limit = 0): EncodedImage; + /** * Return color of pixel at given position on given frame position * diff --git a/tests/Drivers/Gd/Encoders/BmpEncoderTest.php b/tests/Drivers/Gd/Encoders/BmpEncoderTest.php index d5e2480de..8cd4bcf91 100644 --- a/tests/Drivers/Gd/Encoders/BmpEncoderTest.php +++ b/tests/Drivers/Gd/Encoders/BmpEncoderTest.php @@ -12,7 +12,7 @@ /** * @requires extension gd - * @covers \Intervention\Image\Drivers\Gd\Encoders\PngEncoder + * @covers \Intervention\Image\Drivers\Gd\Encoders\BmpEncoder */ class BmpEncoderTest extends TestCase { @@ -28,6 +28,6 @@ public function testEncode(): void $image = $this->getTestImage(); $encoder = new BmpEncoder(); $result = $encoder->encode($image); - $this->assertTrue(MimeSniffer::createFromString($result)->matches(new ImageBmp)); + $this->assertTrue(MimeSniffer::createFromString($result)->matches(ImageBmp::class)); } } diff --git a/tests/Drivers/Imagick/Encoders/BmpEncoderTest.php b/tests/Drivers/Imagick/Encoders/BmpEncoderTest.php index 2ae1dd510..beb20678d 100644 --- a/tests/Drivers/Imagick/Encoders/BmpEncoderTest.php +++ b/tests/Drivers/Imagick/Encoders/BmpEncoderTest.php @@ -7,6 +7,7 @@ use Intervention\Image\Drivers\Imagick\Encoders\BmpEncoder; use Intervention\Image\Drivers\Imagick\Image; use Intervention\Image\Tests\TestCase; +use Intervention\Image\Tests\Traits\CanCreateImagickTestImage; use Intervention\MimeSniffer\MimeSniffer; use Intervention\MimeSniffer\Types\ImageBmp; @@ -16,6 +17,8 @@ */ class BmpEncoderTest extends TestCase { + use CanCreateImagickTestImage; + protected function getTestImage(): Image { $imagick = new Imagick(); @@ -33,4 +36,16 @@ public function testEncode(): void MimeSniffer::createFromString($result)->matches(new ImageBmp()) ); } + + public function testEncodeReduced(): void + { + $image = $this->createTestImage('gradient.bmp'); + $imagick = $image->frame()->core(); + $this->assertEquals(15, $imagick->getImageColors()); + $encoder = new BmpEncoder(2); + $result = $encoder->encode($image); + $imagick = new Imagick(); + $imagick->readImageBlob((string) $result); + $this->assertEquals(2, $imagick->getImageColors()); + } } diff --git a/tests/images/gradient.bmp b/tests/images/gradient.bmp new file mode 100644 index 0000000000000000000000000000000000000000..08661077b45d199b26360417ca4d18aa9a4ab714 GIT binary patch literal 152 zcmZ?roxuPBWk5;;h&iB`k%0v)p#&s_xFHxU04Dx3urd5+m<7cD8U6wBTp$)@_zzV4 z|1bl?kN*q|^+3!H#0>vUfcOFf!)G8T4kW<9P%&%Iz4Xr2XTyLDS0KX#$WR6{gn$f2 IAcKJc05)1CAOHXW literal 0 HcmV?d00001