From 4b7c182152c3c48da8a2e0dfd9573d21cb4a813e Mon Sep 17 00:00:00 2001 From: Oliver Vogel Date: Sun, 31 Oct 2021 07:46:01 +0100 Subject: [PATCH] Color Decoder --- src/Drivers/Gd/Decoders/ArrayColorDecoder.php | 8 +++- src/Drivers/Gd/Decoders/HexColorDecoder.php | 27 +++++++++++++ src/Drivers/Gd/InputHandler.php | 10 +++-- src/Drivers/Gd/Modifiers/FillModifier.php | 10 ++--- .../Imagick/Decoders/ArrayColorDecoder.php | 4 +- .../Imagick/Decoders/HexColorDecoder.php | 27 +++++++++++++ src/Drivers/Imagick/InputHandler.php | 10 +++-- .../Imagick/Modifiers/FillModifier.php | 12 +++--- src/Traits/CanHandleInput.php | 11 +++++ ...teColorArray.php => CanValidateColors.php} | 4 +- tests/Drivers/Gd/InputHandlerTest.php | 40 +++++++++++++++++++ 11 files changed, 137 insertions(+), 26 deletions(-) create mode 100644 src/Drivers/Gd/Decoders/HexColorDecoder.php create mode 100644 src/Drivers/Imagick/Decoders/HexColorDecoder.php create mode 100644 src/Traits/CanHandleInput.php rename src/Traits/{CanValidateColorArray.php => CanValidateColors.php} (85%) diff --git a/src/Drivers/Gd/Decoders/ArrayColorDecoder.php b/src/Drivers/Gd/Decoders/ArrayColorDecoder.php index 7a1b7161..9f8d7a70 100644 --- a/src/Drivers/Gd/Decoders/ArrayColorDecoder.php +++ b/src/Drivers/Gd/Decoders/ArrayColorDecoder.php @@ -7,11 +7,11 @@ use Intervention\Image\Drivers\Gd\Color; use Intervention\Image\Interfaces\ColorInterface; use Intervention\Image\Interfaces\DecoderInterface; use Intervention\Image\Interfaces\ImageInterface; -use Intervention\Image\Traits\CanValidateColorArray; +use Intervention\Image\Traits\CanValidateColors; class ArrayColorDecoder extends AbstractDecoder implements DecoderInterface { - use CanValidateColorArray; + use CanValidateColors; public function decode($input): ImageInterface|ColorInterface { @@ -19,6 +19,10 @@ class ArrayColorDecoder extends AbstractDecoder implements DecoderInterface $this->fail(); } + if (count($input) === 3) { + $input[] = 1; + } + list($r, $g, $b, $a) = $input; return new Color( diff --git a/src/Drivers/Gd/Decoders/HexColorDecoder.php b/src/Drivers/Gd/Decoders/HexColorDecoder.php new file mode 100644 index 00000000..940c327e --- /dev/null +++ b/src/Drivers/Gd/Decoders/HexColorDecoder.php @@ -0,0 +1,27 @@ +fail(); + } + + return parent::decode([ + strlen($matches[1]) == '1' ? hexdec($matches[1] . $matches[1]) : hexdec($matches[1]), + strlen($matches[2]) == '1' ? hexdec($matches[2] . $matches[2]) : hexdec($matches[2]), + strlen($matches[3]) == '1' ? hexdec($matches[3] . $matches[3]) : hexdec($matches[3]), + ]); + } +} diff --git a/src/Drivers/Gd/InputHandler.php b/src/Drivers/Gd/InputHandler.php index 1e95b495..7950e73f 100644 --- a/src/Drivers/Gd/InputHandler.php +++ b/src/Drivers/Gd/InputHandler.php @@ -10,10 +10,12 @@ class InputHandler extends AbstractInputHandler protected function chain(): AbstractDecoder { return new Decoders\ArrayColorDecoder( - new Decoders\FilePathImageDecoder( - new Decoders\BinaryImageDecoder( - new Decoders\DataUriImageDecoder( - new Decoders\Base64ImageDecoder() + new Decoders\HexColorDecoder( + new Decoders\FilePathImageDecoder( + new Decoders\BinaryImageDecoder( + new Decoders\DataUriImageDecoder( + new Decoders\Base64ImageDecoder() + ) ) ) ) diff --git a/src/Drivers/Gd/Modifiers/FillModifier.php b/src/Drivers/Gd/Modifiers/FillModifier.php index 6c3ce2bc..2cf7fd54 100644 --- a/src/Drivers/Gd/Modifiers/FillModifier.php +++ b/src/Drivers/Gd/Modifiers/FillModifier.php @@ -6,9 +6,12 @@ use Intervention\Image\Drivers\Gd\InputHandler; use Intervention\Image\Interfaces\FrameInterface; use Intervention\Image\Interfaces\ImageInterface; use Intervention\Image\Interfaces\ModifierInterface; +use Intervention\Image\Traits\CanHandleInput; class FillModifier implements ModifierInterface { + use CanHandleInput; + public function __construct($filling, ?int $x = null, ?int $y = null) { $this->filling = $filling; @@ -18,7 +21,7 @@ class FillModifier implements ModifierInterface { $width = $image->getWidth(); $height = $image->getHeight(); - $filling = $this->getApplicableFilling(); + $filling = $this->handleInput($this->filling); foreach ($image as $frame) { imagefilledrectangle($frame->getCore(), 0, 0, $width - 1, $height - 1, $filling); @@ -26,9 +29,4 @@ class FillModifier implements ModifierInterface return $image; } - - protected function getApplicableFilling() - { - return (new InputHandler())->handle($this->filling); - } } diff --git a/src/Drivers/Imagick/Decoders/ArrayColorDecoder.php b/src/Drivers/Imagick/Decoders/ArrayColorDecoder.php index e2110744..89f52eeb 100644 --- a/src/Drivers/Imagick/Decoders/ArrayColorDecoder.php +++ b/src/Drivers/Imagick/Decoders/ArrayColorDecoder.php @@ -8,11 +8,11 @@ use Intervention\Image\Drivers\Imagick\Color; use Intervention\Image\Interfaces\ColorInterface; use Intervention\Image\Interfaces\DecoderInterface; use Intervention\Image\Interfaces\ImageInterface; -use Intervention\Image\Traits\CanValidateColorArray; +use Intervention\Image\Traits\CanValidateColors; class ArrayColorDecoder extends AbstractDecoder implements DecoderInterface { - use CanValidateColorArray; + use CanValidateColors; public function decode($input): ImageInterface|ColorInterface { diff --git a/src/Drivers/Imagick/Decoders/HexColorDecoder.php b/src/Drivers/Imagick/Decoders/HexColorDecoder.php new file mode 100644 index 00000000..a0609b34 --- /dev/null +++ b/src/Drivers/Imagick/Decoders/HexColorDecoder.php @@ -0,0 +1,27 @@ +fail(); + } + + return parent::decode([ + strlen($matches[1]) == '1' ? hexdec($matches[1] . $matches[1]) : hexdec($matches[1]), + strlen($matches[2]) == '1' ? hexdec($matches[2] . $matches[2]) : hexdec($matches[2]), + strlen($matches[3]) == '1' ? hexdec($matches[3] . $matches[3]) : hexdec($matches[3]), + ]); + } +} diff --git a/src/Drivers/Imagick/InputHandler.php b/src/Drivers/Imagick/InputHandler.php index d1fcbde2..2062fa71 100644 --- a/src/Drivers/Imagick/InputHandler.php +++ b/src/Drivers/Imagick/InputHandler.php @@ -10,10 +10,12 @@ class InputHandler extends AbstractInputHandler protected function chain(): AbstractDecoder { return new Decoders\ArrayColorDecoder( - new Decoders\FilePathImageDecoder( - new Decoders\BinaryImageDecoder( - new Decoders\DataUriImageDecoder( - new Decoders\Base64ImageDecoder() + new Decoders\HexColorDecoder( + new Decoders\FilePathImageDecoder( + new Decoders\BinaryImageDecoder( + new Decoders\DataUriImageDecoder( + new Decoders\Base64ImageDecoder() + ) ) ) ) diff --git a/src/Drivers/Imagick/Modifiers/FillModifier.php b/src/Drivers/Imagick/Modifiers/FillModifier.php index 3175bb8c..81e20cfd 100644 --- a/src/Drivers/Imagick/Modifiers/FillModifier.php +++ b/src/Drivers/Imagick/Modifiers/FillModifier.php @@ -6,9 +6,12 @@ use ImagickDraw; use Intervention\Image\Drivers\Imagick\InputHandler; use Intervention\Image\Interfaces\ImageInterface; use Intervention\Image\Interfaces\ModifierInterface; +use Intervention\Image\Traits\CanHandleInput; class FillModifier implements ModifierInterface { + use CanHandleInput; + public function __construct($filling, ?int $x = null, ?int $y = null) { $this->filling = $filling; @@ -16,8 +19,10 @@ class FillModifier implements ModifierInterface public function apply(ImageInterface $image): ImageInterface { + $filling = $this->handleInput($this->filling); + $draw = new ImagickDraw(); - $draw->setFillColor($this->getApplicableFilling()->getPixel()); + $draw->setFillColor($filling->getPixel()); $draw->rectangle(0, 0, $image->getWidth(), $image->getHeight()); foreach ($image as $frame) { @@ -26,9 +31,4 @@ class FillModifier implements ModifierInterface return $image; } - - protected function getApplicableFilling() - { - return (new InputHandler())->handle($this->filling); - } } diff --git a/src/Traits/CanHandleInput.php b/src/Traits/CanHandleInput.php new file mode 100644 index 00000000..3182e2af --- /dev/null +++ b/src/Traits/CanHandleInput.php @@ -0,0 +1,11 @@ +handle($value); + } +} diff --git a/src/Traits/CanValidateColorArray.php b/src/Traits/CanValidateColors.php similarity index 85% rename from src/Traits/CanValidateColorArray.php rename to src/Traits/CanValidateColors.php index f06dd940..99f14cb4 100644 --- a/src/Traits/CanValidateColorArray.php +++ b/src/Traits/CanValidateColors.php @@ -2,7 +2,7 @@ namespace Intervention\Image\Traits; -trait CanValidateColorArray +trait CanValidateColors { protected function isValidColorArray($input): bool { @@ -22,7 +22,7 @@ trait CanValidateColorArray } // validate alpha value - if ($input[3] > 1 || $input[3] < 0) { + if (isset($input[3]) && ($input[3] > 1 || $input[3] < 0)) { return false; } diff --git a/tests/Drivers/Gd/InputHandlerTest.php b/tests/Drivers/Gd/InputHandlerTest.php index f4d2d258..41fdf954 100644 --- a/tests/Drivers/Gd/InputHandlerTest.php +++ b/tests/Drivers/Gd/InputHandlerTest.php @@ -58,5 +58,45 @@ class InputHandlerTest extends TestCase $input = [181, 55, 23, .5]; $result = $handler->handle($input); $this->assertInstanceOf(Color::class, $result); + + $handler = new InputHandler(); + $input = [181, 55, 23]; + $result = $handler->handle($input); + $this->assertInstanceOf(Color::class, $result); + } + + public function testHandleHexColor(): void + { + $handler = new InputHandler(); + $input = 'ccff33'; + $result = $handler->handle($input); + $this->assertInstanceOf(Color::class, $result); + $this->assertEquals(204, $result->red()); + $this->assertEquals(255, $result->green()); + $this->assertEquals(51, $result->blue()); + + $handler = new InputHandler(); + $input = 'cf3'; + $result = $handler->handle($input); + $this->assertInstanceOf(Color::class, $result); + $this->assertEquals(204, $result->red()); + $this->assertEquals(255, $result->green()); + $this->assertEquals(51, $result->blue()); + + $handler = new InputHandler(); + $input = '#123456'; + $result = $handler->handle($input); + $this->assertInstanceOf(Color::class, $result); + $this->assertEquals(18, $result->red()); + $this->assertEquals(52, $result->green()); + $this->assertEquals(86, $result->blue()); + + $handler = new InputHandler(); + $input = '#333'; + $result = $handler->handle($input); + $this->assertInstanceOf(Color::class, $result); + $this->assertEquals(51, $result->red()); + $this->assertEquals(51, $result->green()); + $this->assertEquals(51, $result->blue()); } }