1
0
mirror of https://github.com/Intervention/image.git synced 2025-08-30 17:19:50 +02:00

Color Decoder

This commit is contained in:
Oliver Vogel
2021-10-31 07:46:01 +01:00
parent d4eaea5a9e
commit 4b7c182152
11 changed files with 137 additions and 26 deletions

View File

@@ -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(

View File

@@ -0,0 +1,27 @@
<?php
namespace Intervention\Image\Drivers\Gd\Decoders;
use Intervention\Image\Drivers\Gd\Color;
use Intervention\Image\Interfaces\ColorInterface;
use Intervention\Image\Interfaces\DecoderInterface;
use Intervention\Image\Interfaces\ImageInterface;
class HexColorDecoder extends ArrayColorDecoder implements DecoderInterface
{
public function decode($input): ImageInterface|ColorInterface
{
$pattern = '/^#?([a-f0-9]{1,2})([a-f0-9]{1,2})([a-f0-9]{1,2})$/i';
$result = preg_match($pattern, $input, $matches);
if ($result !== 1) {
$this->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]),
]);
}
}

View File

@@ -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()
)
)
)
)

View File

@@ -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);
}
}

View File

@@ -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
{

View File

@@ -0,0 +1,27 @@
<?php
namespace Intervention\Image\Drivers\Imagick\Decoders;
use Intervention\Image\Drivers\Imagick\Color;
use Intervention\Image\Interfaces\ColorInterface;
use Intervention\Image\Interfaces\DecoderInterface;
use Intervention\Image\Interfaces\ImageInterface;
class HexColorDecoder extends ArrayColorDecoder implements DecoderInterface
{
public function decode($input): ImageInterface|ColorInterface
{
$pattern = '/^#?([a-f0-9]{1,2})([a-f0-9]{1,2})([a-f0-9]{1,2})$/i';
$result = preg_match($pattern, $input, $matches);
if ($result !== 1) {
$this->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]),
]);
}
}

View File

@@ -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()
)
)
)
)

View File

@@ -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);
}
}

View File

@@ -0,0 +1,11 @@
<?php
namespace Intervention\Image\Traits;
trait CanHandleInput
{
protected function handleInput($value)
{
return (new InputHandler())->handle($value);
}
}

View File

@@ -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;
}

View File

@@ -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());
}
}