Skip to content

Commit

Permalink
Implement color limit for Bitmap encoders
Browse files Browse the repository at this point in the history
  • Loading branch information
olivervogel committed Oct 31, 2023
1 parent b8d6023 commit ba9272b
Show file tree
Hide file tree
Showing 7 changed files with 48 additions and 8 deletions.
8 changes: 4 additions & 4 deletions src/Drivers/Abstract/AbstractImage.php
Expand Up @@ -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
Expand Down
13 changes: 11 additions & 2 deletions src/Drivers/Gd/Encoders/BmpEncoder.php
Expand Up @@ -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');
Expand Down
9 changes: 9 additions & 0 deletions src/Drivers/Imagick/Encoders/BmpEncoder.php
Expand Up @@ -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';
Expand All @@ -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');
}
Expand Down
7 changes: 7 additions & 0 deletions src/Interfaces/ImageInterface.php
Expand Up @@ -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
*
Expand Down
4 changes: 2 additions & 2 deletions tests/Drivers/Gd/Encoders/BmpEncoderTest.php
Expand Up @@ -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
{
Expand All @@ -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));
}
}
15 changes: 15 additions & 0 deletions tests/Drivers/Imagick/Encoders/BmpEncoderTest.php
Expand Up @@ -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;

Expand All @@ -16,6 +17,8 @@
*/
class BmpEncoderTest extends TestCase
{
use CanCreateImagickTestImage;

protected function getTestImage(): Image
{
$imagick = new Imagick();
Expand All @@ -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());
}
}
Binary file added tests/images/gradient.bmp
Binary file not shown.

0 comments on commit ba9272b

Please sign in to comment.