diff --git a/docker-compose.yml b/docker-compose.yml index e32993d7..8d90fbff 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -4,7 +4,7 @@ services: tests: build: ./ working_dir: /project - command: bash -c "composer install && ./vendor/bin/phpunit -vvv --filter=InputHandlerTest" + command: bash -c "composer install && ./vendor/bin/phpunit -vvv" volumes: - ./:/project analysis: diff --git a/src/Colors/Cmyk/Channels/Cyan.php b/src/Colors/Cmyk/Channels/Cyan.php index cb40daac..213fea38 100644 --- a/src/Colors/Cmyk/Channels/Cyan.php +++ b/src/Colors/Cmyk/Channels/Cyan.php @@ -42,4 +42,14 @@ class Cyan implements ColorChannelInterface return $value; } + + public function toString(): string + { + return (string) $this->value(); + } + + public function __toString(): string + { + return $this->toString(); + } } diff --git a/src/Colors/Cmyk/Color.php b/src/Colors/Cmyk/Color.php index 26b423ea..74ee0540 100644 --- a/src/Colors/Cmyk/Color.php +++ b/src/Colors/Cmyk/Color.php @@ -91,7 +91,7 @@ class Color implements ColorInterface return $this->convertTo(CmykColorspace::class); } - public function __toString(): string + public function toString(): string { return sprintf( 'cmyk(%d, %d, %d, %d)', @@ -101,4 +101,9 @@ class Color implements ColorInterface $this->key()->value() ); } + + public function __toString(): string + { + return $this->toString(); + } } diff --git a/src/Colors/Cmyk/Parser.php b/src/Colors/Cmyk/Parser.php new file mode 100644 index 00000000..15fb3a70 --- /dev/null +++ b/src/Colors/Cmyk/Parser.php @@ -0,0 +1,34 @@ +[0-9\.]+)%?, ?(?P[0-9\.]+)%?, ?(?P[0-9\.]+)%?, ?(?P[0-9\.]+)%?\)$/'; + $result = preg_match($pattern, $input, $matches); + if ($result === 1) { + return new Color( + intval(round(floatval($matches['c']))), + intval(round(floatval($matches['m']))), + intval(round(floatval($matches['y']))), + intval(round(floatval($matches['k']))) + ); + } + + throw new ColorException('Unable to parse color'); + } +} diff --git a/src/Colors/Parser.php b/src/Colors/Parser.php new file mode 100644 index 00000000..edd2b2b4 --- /dev/null +++ b/src/Colors/Parser.php @@ -0,0 +1,28 @@ +value(); + } + + public function __toString(): string + { + return $this->toString(); + } } diff --git a/src/Colors/Rgb/Color.php b/src/Colors/Rgb/Color.php index 644b3936..b630829e 100644 --- a/src/Colors/Rgb/Color.php +++ b/src/Colors/Rgb/Color.php @@ -87,7 +87,7 @@ class Color implements ColorInterface return $this->convertTo(RgbaColorspace::class); } - public function __toString(): string + public function toString(): string { return sprintf( 'rgb(%d, %d, %d)', @@ -96,4 +96,9 @@ class Color implements ColorInterface $this->blue()->value() ); } + + public function __toString(): string + { + return $this->toString(); + } } diff --git a/src/Colors/Rgb/Parser.php b/src/Colors/Rgb/Parser.php index be787dab..82aef1e6 100644 --- a/src/Colors/Rgb/Parser.php +++ b/src/Colors/Rgb/Parser.php @@ -6,6 +6,33 @@ use Intervention\Image\Exceptions\ColorException; class Parser { + public static function parse(mixed $value): Color + { + if (!is_string($value)) { + throw new ColorException('Unable to parse color'); + } + + try { + return static::fromHex($value); + } catch (ColorException $e) { + # move on + } + + try { + return static::fromString($value); + } catch (ColorException $e) { + # move on + } + + try { + return static::fromName($value); + } catch (ColorException $e) { + # move on + } + + throw new ColorException('Unable to parse color'); + } + public static function fromHex(string $input): Color { $pattern = '/^#?(?P[0-9a-f]{3}|[0-9a-f]{6})$/i'; @@ -30,14 +57,29 @@ class Parser public static function fromString(string $input): Color { - $pattern = '/^rgb\((?P[0-9]{1,3}), ?(?P[0-9]{1,3}), ?(?P[0-9]{1,3})\)$/'; + // rgb(255, 255, 255) + $pattern = '/^s?rgb\((?P[0-9]{1,3}), ?(?P[0-9]{1,3}), ?(?P[0-9]{1,3})\)$/'; $result = preg_match($pattern, $input, $matches); - - if ($result !== 1) { - throw new ColorException('Unable to parse color'); + if ($result === 1) { + return new Color( + $matches['r'], + $matches['g'], + $matches['b'] + ); } - return new Color($matches['r'], $matches['g'], $matches['b']); + // rgb(100%, 100%, 100%) + $pattern = '/^s?rgb\((?P[0-9\.]+)%, ?(?P[0-9\.]+)%, ?(?P[0-9\.]+)%\)$/'; + $result = preg_match($pattern, $input, $matches); + if ($result === 1) { + return new Color( + intval(round(floatval($matches['r']) / 100 * 255)), + intval(round(floatval($matches['g']) / 100 * 255)), + intval(round(floatval($matches['b']) / 100 * 255)) + ); + } + + throw new ColorException('Unable to parse color'); } public static function fromName(string $input): Color diff --git a/src/Colors/Rgba/Channels/Alpha.php b/src/Colors/Rgba/Channels/Alpha.php index 46d3a152..e69a437e 100644 --- a/src/Colors/Rgba/Channels/Alpha.php +++ b/src/Colors/Rgba/Channels/Alpha.php @@ -4,5 +4,13 @@ namespace Intervention\Image\Colors\Rgba\Channels; class Alpha extends Red { - // + public function toString(): string + { + return strval(round($this->normalize(), 6)); + } + + public function __toString(): string + { + return $this->toString(); + } } diff --git a/src/Colors/Rgba/Color.php b/src/Colors/Rgba/Color.php index 90e65827..8bfdf227 100644 --- a/src/Colors/Rgba/Color.php +++ b/src/Colors/Rgba/Color.php @@ -81,7 +81,7 @@ class Color extends RgbColor return $this->convertTo(CmykColorspace::class); } - public function __toString(): string + public function toString(): string { return sprintf( 'rgba(%d, %d, %d, %.1F)', @@ -91,4 +91,9 @@ class Color extends RgbColor $this->alpha()->normalize(), ); } + + public function __toString(): string + { + return $this->toString(); + } } diff --git a/src/Colors/Rgba/Parser.php b/src/Colors/Rgba/Parser.php index a567f70e..efaa9f70 100644 --- a/src/Colors/Rgba/Parser.php +++ b/src/Colors/Rgba/Parser.php @@ -38,18 +38,31 @@ class Parser extends RgbParser public static function fromString(string $input): Color { - $pattern = '/^rgba\((?P[0-9]{1,3}), *(?P[0-9]{1,3}), *(?P[0-9]{1,3}), *(?P((1|0))?(\.[0-9]+)?)\)$/'; + // rgba(255, 255, 255, 1.0) + $pattern = '/^s?rgba\((?P[0-9]{1,3}), *(?P[0-9]{1,3}), *(?P[0-9]{1,3}), *(?P((1|0))?(\.[0-9]+)?)\)$/'; $result = preg_match($pattern, $input, $matches); - if ($result !== 1) { - throw new ColorException('Unable to parse color'); + if ($result === 1) { + return new Color( + $matches['r'], + $matches['g'], + $matches['b'], + intval(round(floatval($matches['a']) * 255)) + ); } - return new Color( - $matches['r'], - $matches['g'], - $matches['b'], - intval(round(floatval($matches['a']) * 255)) - ); + // rgba(100%, 100%, 100%, 100%) + $pattern = '/s?rgba\((?P[0-9\.]+)%, ?(?P[0-9\.]+)%, ?(?P[0-9\.]+)%, ?(?P[0-9\.]+)%\)/'; + $result = preg_match($pattern, $input, $matches); + if ($result === 1) { + return new Color( + intval(round(floatval($matches['r']) / 100 * 255)), + intval(round(floatval($matches['g']) / 100 * 255)), + intval(round(floatval($matches['b']) / 100 * 255)), + intval(round(floatval($matches['a']) / 100 * 255)) + ); + } + + throw new ColorException('Unable to parse color'); } } diff --git a/src/Drivers/Gd/Color.php b/src/Drivers/Gd/Color.php deleted file mode 100644 index d4cde720..00000000 --- a/src/Drivers/Gd/Color.php +++ /dev/null @@ -1,50 +0,0 @@ -toArray()[0]; - } - - public function green(): int - { - return $this->toArray()[1]; - } - - public function blue(): int - { - return $this->toArray()[2]; - } - - public function alpha(): float - { - return $this->toArray()[3]; - } - - public function toArray(): array - { - $a = ($this->value >> 24) & 0x7F; - $r = ($this->value >> 16) & 0xFF; - $g = ($this->value >> 8) & 0xFF; - $b = $this->value & 0xFF; - $a = (float) round(1 - $a / 127, 2); - - return [$r, $g, $b, $a]; - } - - public function toInt(): int - { - return $this->value; - } -} diff --git a/src/Drivers/Gd/ColorTransformer.php b/src/Drivers/Gd/ColorTransformer.php new file mode 100644 index 00000000..aac312e7 --- /dev/null +++ b/src/Drivers/Gd/ColorTransformer.php @@ -0,0 +1,61 @@ +> 24) & 0xFF; + $r = ($value >> 16) & 0xFF; + $g = ($value >> 8) & 0xFF; + $b = $value & 0xFF; + + // convert gd apha integer to intervention alpha integer + // ([opaque]0-127[transparent]) to ([opaque]255-0[transparent]) + $a = (int) static::convertRange($a, 127, 0, 0, 255); + + return new Color($r, $g, $b, $a); + } + + /** + * Transforms given color to the corresponding GD Library integer value + * + * @param ColorInterface $color + * @return int + */ + public static function colorToInteger(ColorInterface $color): int + { + $color = $color->toRgba(); + + $r = $color->red()->value(); + $g = $color->green()->value(); + $b = $color->blue()->value(); + $a = $color->alpha()->value(); + + // convert alpha value to gd alpha + // ([opaque]255-0[transparent]) to ([opaque]0-127[transparent]) + $a = (int) static::convertRange($a, 0, 255, 127, 0); + + return ($a << 24) + ($r << 16) + ($g << 8) + $b; + } + + private static function convertRange( + float|int $input, + float|int $min, + float|int $max, + float|int $targetMin, + float|int $targetMax + ): float|int { + return ceil(((($input - $min) * ($targetMax - $targetMin)) / ($max - $min)) + $targetMin); + } +} diff --git a/src/Drivers/Gd/Decoders/TransparentColorDecoder.php b/src/Drivers/Gd/Decoders/ColorObjectDecoder.php similarity index 65% rename from src/Drivers/Gd/Decoders/TransparentColorDecoder.php rename to src/Drivers/Gd/Decoders/ColorObjectDecoder.php index 5cdd3d02..7c2e83a4 100644 --- a/src/Drivers/Gd/Decoders/TransparentColorDecoder.php +++ b/src/Drivers/Gd/Decoders/ColorObjectDecoder.php @@ -2,19 +2,20 @@ namespace Intervention\Image\Drivers\Gd\Decoders; +use Intervention\Image\Drivers\Abstract\Decoders\AbstractDecoder; use Intervention\Image\Exceptions\DecoderException; use Intervention\Image\Interfaces\ColorInterface; use Intervention\Image\Interfaces\DecoderInterface; use Intervention\Image\Interfaces\ImageInterface; -class TransparentColorDecoder extends RgbArrayColorDecoder implements DecoderInterface +class ColorObjectDecoder extends AbstractDecoder implements DecoderInterface { public function decode($input): ImageInterface|ColorInterface { - if (! is_string($input) || strtolower($input) !== 'transparent') { + if (! is_a($input, ColorInterface::class)) { throw new DecoderException('Unable to decode input'); } - return parent::decode([0, 0, 0, 0]); + return $input; } } diff --git a/src/Drivers/Gd/Image.php b/src/Drivers/Gd/Image.php index ad9b3754..b572354b 100644 --- a/src/Drivers/Gd/Image.php +++ b/src/Drivers/Gd/Image.php @@ -69,7 +69,7 @@ class Image extends AbstractImage implements ImageInterface, IteratorAggregate public function pickColor(int $x, int $y, int $frame_key = 0): ?ColorInterface { if ($frame = $this->getFrame($frame_key)) { - return new Color(imagecolorat($frame->getCore(), $x, $y)); + return ColorTransformer::colorFromInteger(imagecolorat($frame->getCore(), $x, $y)); } return null; diff --git a/src/Drivers/Gd/InputHandler.php b/src/Drivers/Gd/InputHandler.php index 42785e59..076269c8 100644 --- a/src/Drivers/Gd/InputHandler.php +++ b/src/Drivers/Gd/InputHandler.php @@ -8,6 +8,7 @@ class InputHandler extends AbstractInputHandler { protected $decoders = [ Decoders\ImageObjectDecoder::class, + Decoders\ColorObjectDecoder::class, Decoders\FilePointerImageDecoder::class, Decoders\HtmlColorNameDecoder::class, Decoders\HexColorDecoder::class, diff --git a/src/Drivers/Gd/Modifiers/FillModifier.php b/src/Drivers/Gd/Modifiers/FillModifier.php index 0f747342..0d0ea3f3 100644 --- a/src/Drivers/Gd/Modifiers/FillModifier.php +++ b/src/Drivers/Gd/Modifiers/FillModifier.php @@ -2,6 +2,7 @@ namespace Intervention\Image\Drivers\Gd\Modifiers; +use Intervention\Image\Drivers\Gd\ColorTransformer; use Intervention\Image\Drivers\Gd\Frame; use Intervention\Image\Geometry\Point; use Intervention\Image\Interfaces\ColorInterface; @@ -10,9 +11,11 @@ use Intervention\Image\Interfaces\ModifierInterface; class FillModifier implements ModifierInterface { + protected $gd_color; + public function __construct(protected ColorInterface $color, protected ?Point $position = null) { - // + $this->gd_color = ColorTransformer::colorToInteger($color); } public function apply(ImageInterface $image): ImageInterface @@ -34,7 +37,7 @@ class FillModifier implements ModifierInterface $frame->getCore(), $this->position->getX(), $this->position->getY(), - $this->color->toInt() + $this->gd_color ); } @@ -47,7 +50,7 @@ class FillModifier implements ModifierInterface 0, $frame->getSize()->getWidth() - 1, $frame->getSize()->getHeight() - 1, - $this->color->toInt() + $this->gd_color ); } diff --git a/src/Drivers/Imagick/Color.php b/src/Drivers/Imagick/Color.php deleted file mode 100644 index 7503c7b1..00000000 --- a/src/Drivers/Imagick/Color.php +++ /dev/null @@ -1,61 +0,0 @@ -pixel; - } - - public function red(): int - { - return intval(round($this->pixel->getColorValue(Imagick::COLOR_RED) * 255)); - } - - public function green(): int - { - return intval(round($this->pixel->getColorValue(Imagick::COLOR_GREEN) * 255)); - } - - public function blue(): int - { - return intval(round($this->pixel->getColorValue(Imagick::COLOR_BLUE) * 255)); - } - - public function alpha(): float - { - return round($this->pixel->getColorValue(Imagick::COLOR_ALPHA), 2); - } - - public function toArray(): array - { - return [ - $this->red(), - $this->green(), - $this->blue(), - $this->alpha() - ]; - } - - public function toInt(): int - { - $r = $this->red(); - $g = $this->green(); - $b = $this->blue(); - $a = intval(round($this->alpha() * 255)); - - return intval(($a << 24) + ($r << 16) + ($g << 8) + $b); - } -} diff --git a/src/Drivers/Imagick/ColorTransformer.php b/src/Drivers/Imagick/ColorTransformer.php new file mode 100644 index 00000000..1ddf8a32 --- /dev/null +++ b/src/Drivers/Imagick/ColorTransformer.php @@ -0,0 +1,32 @@ +getColorAsString()); + } + + /** + * Transforms given color to the corresponding ImagickPixel + * + * @param ColorInterface $color + * @return ImagickPixel + */ + public static function colorToPixel(ColorInterface $color): ImagickPixel + { + return new ImagickPixel($color->toString()); + } +} diff --git a/src/Drivers/Imagick/Decoders/TransparentColorDecoder.php b/src/Drivers/Imagick/Decoders/ColorObjectDecoder.php similarity index 66% rename from src/Drivers/Imagick/Decoders/TransparentColorDecoder.php rename to src/Drivers/Imagick/Decoders/ColorObjectDecoder.php index 097a35ff..426d2e52 100644 --- a/src/Drivers/Imagick/Decoders/TransparentColorDecoder.php +++ b/src/Drivers/Imagick/Decoders/ColorObjectDecoder.php @@ -2,19 +2,20 @@ namespace Intervention\Image\Drivers\Imagick\Decoders; +use Intervention\Image\Drivers\Abstract\Decoders\AbstractDecoder; use Intervention\Image\Exceptions\DecoderException; use Intervention\Image\Interfaces\ColorInterface; use Intervention\Image\Interfaces\DecoderInterface; use Intervention\Image\Interfaces\ImageInterface; -class TransparentColorDecoder extends RgbArrayColorDecoder implements DecoderInterface +class ColorObjectDecoder extends AbstractDecoder implements DecoderInterface { public function decode($input): ImageInterface|ColorInterface { - if (! is_string($input) || strtolower($input) !== 'transparent') { + if (! is_a($input, ColorInterface::class)) { throw new DecoderException('Unable to decode input'); } - return parent::decode([0, 0, 0, 0]); + return $input; } } diff --git a/src/Drivers/Imagick/Image.php b/src/Drivers/Imagick/Image.php index 4dc8ca6a..a6ac13e5 100644 --- a/src/Drivers/Imagick/Image.php +++ b/src/Drivers/Imagick/Image.php @@ -124,7 +124,9 @@ class Image extends AbstractImage implements ImageInterface, Iterator public function pickColor(int $x, int $y, int $frame_key = 0): ?ColorInterface { if ($frame = $this->getFrame($frame_key)) { - return new Color($frame->getCore()->getImagePixelColor($x, $y)); + return ColorTransformer::colorFromPixel( + $frame->getCore()->getImagePixelColor($x, $y) + ); } return null; diff --git a/src/Drivers/Imagick/InputHandler.php b/src/Drivers/Imagick/InputHandler.php index 0fc798ff..d6ec81ef 100644 --- a/src/Drivers/Imagick/InputHandler.php +++ b/src/Drivers/Imagick/InputHandler.php @@ -8,6 +8,7 @@ class InputHandler extends AbstractInputHandler { protected $decoders = [ Decoders\ImageObjectDecoder::class, + Decoders\ColorObjectDecoder::class, Decoders\FilePointerImageDecoder::class, Decoders\HtmlColorNameDecoder::class, Decoders\HexColorDecoder::class, diff --git a/src/Drivers/Imagick/Modifiers/FillModifier.php b/src/Drivers/Imagick/Modifiers/FillModifier.php index a6cc51a4..36bef1af 100644 --- a/src/Drivers/Imagick/Modifiers/FillModifier.php +++ b/src/Drivers/Imagick/Modifiers/FillModifier.php @@ -4,19 +4,23 @@ namespace Intervention\Image\Drivers\Imagick\Modifiers; use Imagick; use ImagickDraw; -use Intervention\Image\Drivers\Imagick\Color; +use ImagickPixel; +use Intervention\Image\Drivers\Imagick\ColorTransformer; use Intervention\Image\Drivers\Imagick\Frame; use Intervention\Image\Geometry\Point; +use Intervention\Image\Interfaces\ColorInterface; use Intervention\Image\Interfaces\ImageInterface; use Intervention\Image\Interfaces\ModifierInterface; class FillModifier implements ModifierInterface { + protected ImagickPixel $pixel; + public function __construct( - protected Color $color, + protected ColorInterface $color, protected ?Point $position = null ) { - // + $this->pixel = ColorTransformer::colorToPixel($color); } public function apply(ImageInterface $image): ImageInterface @@ -40,7 +44,7 @@ class FillModifier implements ModifierInterface ); $frame->getCore()->floodfillPaintImage( - $this->color->getPixel(), + $this->pixel, 100, $target, $this->position->getX(), @@ -53,7 +57,7 @@ class FillModifier implements ModifierInterface protected function fillAllWithColor(Frame $frame): void { $draw = new ImagickDraw(); - $draw->setFillColor($this->color->getPixel()); + $draw->setFillColor($this->pixel); $draw->rectangle( 0, 0, diff --git a/src/Drivers/Imagick/Traits/CanReadColors.php b/src/Drivers/Imagick/Traits/CanReadColors.php new file mode 100644 index 00000000..aba65d76 --- /dev/null +++ b/src/Drivers/Imagick/Traits/CanReadColors.php @@ -0,0 +1,14 @@ +toString()); + } +} diff --git a/src/Interfaces/ColorChannelInterface.php b/src/Interfaces/ColorChannelInterface.php index 82de01da..6c3c7ce8 100644 --- a/src/Interfaces/ColorChannelInterface.php +++ b/src/Interfaces/ColorChannelInterface.php @@ -9,4 +9,6 @@ interface ColorChannelInterface public function validate(mixed $value): mixed; public function min(): int; public function max(): int; + public function toString(): string; + public function __toString(): string; } diff --git a/src/Interfaces/ColorInterface.php b/src/Interfaces/ColorInterface.php index 1333e94b..46a4dab8 100644 --- a/src/Interfaces/ColorInterface.php +++ b/src/Interfaces/ColorInterface.php @@ -8,14 +8,15 @@ use Intervention\Image\Colors\Rgba\Color as RgbaColor; interface ColorInterface { - // public function toRgb(): RgbColor; - // public function toRgba(): RgbaColor; - // public function toCmyk(): CmykColor; + public function toRgb(): RgbColor; + public function toRgba(): RgbaColor; + public function toCmyk(): CmykColor; + public function toArray(): array; + public function toString(): string; + public function __toString(): string; // public function channels(): array; // public function channel(string $classname): ColorChannelInterface; // public function colorspace(): ColorspaceInterface; - // public function toArray(): array; // public function convertTo(string|ColorspaceInterface $colorspace): ColorInterface; - // public function __toString(): string; } diff --git a/tests/Colors/Cmyk/ParserTest.php b/tests/Colors/Cmyk/ParserTest.php new file mode 100644 index 00000000..b94ec4f2 --- /dev/null +++ b/tests/Colors/Cmyk/ParserTest.php @@ -0,0 +1,32 @@ +assertInstanceOf(Color::class, $color); + $this->assertEquals([100, 0, 0, 0], $color->toArray()); + } + + public function testFromString(): void + { + $color = Parser::fromString('cmyk(100, 0, 0, 0)'); + $this->assertInstanceOf(Color::class, $color); + $this->assertEquals([100, 0, 0, 0], $color->toArray()); + + $color = Parser::fromString('cmyk(100%, 0%, 0%, 0%)'); + $this->assertInstanceOf(Color::class, $color); + $this->assertEquals([100, 0, 0, 0], $color->toArray()); + } +} diff --git a/tests/Colors/ParserTest.php b/tests/Colors/ParserTest.php new file mode 100644 index 00000000..a783f62a --- /dev/null +++ b/tests/Colors/ParserTest.php @@ -0,0 +1,47 @@ +assertInstanceOf(RgbColor::class, $color); + $this->assertEquals([204, 204, 204], $color->toArray()); + + $color = Parser::parse('rgb(204, 204, 204)'); + $this->assertInstanceOf(RgbColor::class, $color); + $this->assertEquals([204, 204, 204], $color->toArray()); + + $color = Parser::parse('rgba(204, 204, 204, 1)'); + $this->assertInstanceOf(RgbaColor::class, $color); + $this->assertEquals([204, 204, 204, 255], $color->toArray()); + + $color = Parser::parse('cccc'); + $this->assertInstanceOf(RgbColor::class, $color); + $this->assertEquals([204, 204, 204, 204], $color->toArray()); + + $color = Parser::parse('cccccccc'); + $this->assertInstanceOf(RgbColor::class, $color); + $this->assertEquals([204, 204, 204, 204], $color->toArray()); + + $color = Parser::parse('salmon'); + $this->assertInstanceOf(RgbColor::class, $color); + $this->assertEquals('fa8072', $color->toHex()); + + $color = Parser::parse('cmyk(100, 100, 0,0)'); + $this->assertInstanceOf(CmykColor::class, $color); + $this->assertEquals([100, 100, 0, 0], $color->toArray()); + } +} diff --git a/tests/Colors/Rgb/ParserTest.php b/tests/Colors/Rgb/ParserTest.php index 08389cbf..b6ccce7d 100644 --- a/tests/Colors/Rgb/ParserTest.php +++ b/tests/Colors/Rgb/ParserTest.php @@ -13,6 +13,21 @@ use Intervention\Image\Tests\TestCase; */ class ParserTest extends TestCase { + public function testParse(): void + { + $color = Parser::parse('ccc'); + $this->assertInstanceOf(Color::class, $color); + $this->assertEquals([204, 204, 204], $color->toArray()); + + $color = Parser::parse('rgb(204, 204, 204)'); + $this->assertInstanceOf(Color::class, $color); + $this->assertEquals([204, 204, 204], $color->toArray()); + + $color = Parser::parse('salmon'); + $this->assertInstanceOf(Color::class, $color); + $this->assertEquals('fa8072', $color->toHex()); + } + public function testFromHex(): void { $color = Parser::fromHex('ccc'); @@ -41,6 +56,14 @@ class ParserTest extends TestCase $this->assertInstanceOf(Color::class, $color); $this->assertEquals([204, 204, 204], $color->toArray()); + $color = Parser::fromString('rgb(100%,20%,25%)'); + $this->assertInstanceOf(Color::class, $color); + $this->assertEquals([255, 51, 64], $color->toArray()); + + $color = Parser::fromString('rgb(100%,74.8064%,25.2497%)'); + $this->assertInstanceOf(Color::class, $color); + $this->assertEquals([255, 191, 64], $color->toArray()); + $this->expectException(ColorException::class); (new Parser())->fromString('rgb(204,204,204,1)'); diff --git a/tests/Colors/Rgba/ChannelTest.php b/tests/Colors/Rgba/ChannelTest.php index a1144e40..3edcca17 100644 --- a/tests/Colors/Rgba/ChannelTest.php +++ b/tests/Colors/Rgba/ChannelTest.php @@ -3,6 +3,7 @@ namespace Intervention\Image\Tests\Colors\Rgba; use Intervention\Image\Colors\Rgba\Channels\Red as Channel; +use Intervention\Image\Colors\Rgba\Channels\Alpha as Alpha; use Intervention\Image\Exceptions\ColorException; use Intervention\Image\Tests\TestCase; @@ -45,4 +46,22 @@ class ChannelTest extends TestCase $this->expectException(ColorException::class); new Channel(-1); } + + public function testToString(): void + { + $channel = new Channel(255); + $this->assertEquals("255", $channel->toString()); + + $channel = new Alpha(0); + $this->assertEquals("0", $channel->toString()); + + $channel = new Alpha(51); + $this->assertEquals("0.2", $channel->toString()); + + $channel = new Alpha(255); + $this->assertEquals("1", $channel->toString()); + + $channel = new Alpha(170); + $this->assertEquals("0.666667", $channel->toString()); + } } diff --git a/tests/Colors/Rgba/ParserTest.php b/tests/Colors/Rgba/ParserTest.php index 0986c797..89441646 100644 --- a/tests/Colors/Rgba/ParserTest.php +++ b/tests/Colors/Rgba/ParserTest.php @@ -13,6 +13,21 @@ use Intervention\Image\Tests\TestCase; */ class ParserTest extends TestCase { + public function testParse(): void + { + $color = Parser::parse('ccc'); + $this->assertInstanceOf(Color::class, $color); + $this->assertEquals([204, 204, 204, 255], $color->toArray()); + + $color = Parser::parse('rgba(204, 204, 204, 1)'); + $this->assertInstanceOf(Color::class, $color); + $this->assertEquals([204, 204, 204, 255], $color->toArray()); + + $color = Parser::parse('salmon'); + $this->assertInstanceOf(Color::class, $color); + $this->assertEquals('fa8072', $color->toHex()); + } + public function testFromHex(): void { $color = Parser::fromHex('ccc'); @@ -62,6 +77,14 @@ class ParserTest extends TestCase $this->assertInstanceOf(Color::class, $color); $this->assertEquals([204, 204, 204, 51], $color->toArray()); + $color = Parser::fromString('rgba(100%,20%,25%,100%)'); + $this->assertInstanceOf(Color::class, $color); + $this->assertEquals([255, 51, 64, 255], $color->toArray()); + + $color = Parser::fromString('rgba(100%,74.8064%,25.2497%,100%)'); + $this->assertInstanceOf(Color::class, $color); + $this->assertEquals([255, 191, 64, 255], $color->toArray()); + $this->expectException(ColorException::class); $color = Parser::fromString('rgba(204, 204, 204, 1.2)'); } diff --git a/tests/Drivers/Gd/ColorTransformerTest.php b/tests/Drivers/Gd/ColorTransformerTest.php new file mode 100644 index 00000000..24a3fa7c --- /dev/null +++ b/tests/Drivers/Gd/ColorTransformerTest.php @@ -0,0 +1,30 @@ +assertInstanceOf(Color::class, $result); + $this->assertEquals([181, 55, 23, 155], $result->toArray()); + + $result = ColorTransformer::colorFromInteger(16777215); + $this->assertInstanceOf(Color::class, $result); + $this->assertEquals([255, 255, 255, 255], $result->toArray()); + } + + public function testToInteger(): void + { + $result = ColorTransformer::colorToInteger(new Color(181, 55, 23, 155)); + $this->assertEquals(850736919, $result); + + $result = ColorTransformer::colorToInteger(new Color(255, 255, 255, 255)); + $this->assertEquals(16777215, $result); + } +} diff --git a/tests/Drivers/Gd/Decoders/HexColorDecoderTest.php b/tests/Drivers/Gd/Decoders/HexColorDecoderTest.php index 179f4620..f78468ab 100644 --- a/tests/Drivers/Gd/Decoders/HexColorDecoderTest.php +++ b/tests/Drivers/Gd/Decoders/HexColorDecoderTest.php @@ -2,7 +2,7 @@ namespace Intervention\Image\Tests\Drivers\Gd\Decoders; -use Intervention\Image\Drivers\Gd\Color; +use Intervention\Image\Colors\Rgb\Color; use Intervention\Image\Drivers\Gd\Decoders\HexColorDecoder; use Intervention\Image\Tests\TestCase; diff --git a/tests/Drivers/Gd/Decoders/HtmlColorNameDecoderTest.php b/tests/Drivers/Gd/Decoders/HtmlColorNameDecoderTest.php index 8b713599..1113c784 100644 --- a/tests/Drivers/Gd/Decoders/HtmlColorNameDecoderTest.php +++ b/tests/Drivers/Gd/Decoders/HtmlColorNameDecoderTest.php @@ -2,7 +2,7 @@ namespace Intervention\Image\Tests\Drivers\Gd\Decoders; -use Intervention\Image\Drivers\Gd\Color; +use Intervention\Image\Colors\Rgb\Color; use Intervention\Image\Drivers\Gd\Decoders\HtmlColorNameDecoder; use Intervention\Image\Tests\TestCase; diff --git a/tests/Drivers/Gd/Decoders/RgbStringColorDecoderTest.php b/tests/Drivers/Gd/Decoders/RgbStringColorDecoderTest.php index 45537a27..fa73370c 100644 --- a/tests/Drivers/Gd/Decoders/RgbStringColorDecoderTest.php +++ b/tests/Drivers/Gd/Decoders/RgbStringColorDecoderTest.php @@ -2,7 +2,8 @@ namespace Intervention\Image\Tests\Drivers\Gd\Decoders; -use Intervention\Image\Drivers\Gd\Color; +use Intervention\Image\Colors\Rgb\Color as RgbColor; +use Intervention\Image\Colors\Rgba\Color as RgbaColor; use Intervention\Image\Drivers\Gd\Decoders\RgbStringColorDecoder; use Intervention\Image\Tests\TestCase; @@ -16,21 +17,15 @@ class RgbStringColorDecoderTest extends TestCase { $decoder = new RgbStringColorDecoder(); $color = $decoder->decode('rgb(181, 55, 23)'); - $this->assertInstanceOf(Color::class, $color); - $this->assertEquals(181, $color->red()); - $this->assertEquals(55, $color->green()); - $this->assertEquals(23, $color->blue()); - $this->assertEquals(1, $color->alpha()); + $this->assertInstanceOf(RgbColor::class, $color); + $this->assertEquals([181, 55, 23], $color->toArray()); } public function testDecodeRgba(): void { $decoder = new RgbStringColorDecoder(); $color = $decoder->decode('rgba(181, 55, 23, 0.5)'); - $this->assertInstanceOf(Color::class, $color); - $this->assertEquals(181, $color->red()); - $this->assertEquals(55, $color->green()); - $this->assertEquals(23, $color->blue()); - $this->assertEquals(.5, $color->alpha()); + $this->assertInstanceOf(RgbaColor::class, $color); + $this->assertEquals([181, 55, 23, 51], $color->toArray()); } } diff --git a/tests/Drivers/Gd/Decoders/TransparentColorDecoderTest.php b/tests/Drivers/Gd/Decoders/TransparentColorDecoderTest.php deleted file mode 100644 index f680a367..00000000 --- a/tests/Drivers/Gd/Decoders/TransparentColorDecoderTest.php +++ /dev/null @@ -1,25 +0,0 @@ -decode('transparent'); - $this->assertInstanceOf(Color::class, $color); - $this->assertEquals(0, $color->red()); - $this->assertEquals(0, $color->green()); - $this->assertEquals(0, $color->blue()); - $this->assertEquals(0, $color->alpha()); - } -} diff --git a/tests/Drivers/Imagick/ColorTransformerTest.php b/tests/Drivers/Imagick/ColorTransformerTest.php new file mode 100644 index 00000000..fa71db90 --- /dev/null +++ b/tests/Drivers/Imagick/ColorTransformerTest.php @@ -0,0 +1,37 @@ +assertInstanceOf(Color::class, $result); + $this->assertEquals([181, 55, 23, 153], $result->toArray()); + + $result = ColorTransformer::colorFromPixel(new ImagickPixel('rgba(255, 255, 255, 1)')); + $this->assertInstanceOf(Color::class, $result); + $this->assertEquals([255, 255, 255, 255], $result->toArray()); + } + + public function testToPixel(): void + { + $result = ColorTransformer::colorToPixel(new Color(181, 55, 23, 153)); + $this->assertInstanceOf(ImagickPixel::class, $result); + $this->assertEquals('srgba(181,55,23,0.6)', $result->getColorAsString()); + + $result = ColorTransformer::colorToPixel(new Color(255, 255, 255, 255)); + $this->assertInstanceOf(ImagickPixel::class, $result); + $this->assertEquals('srgba(255,255,255,1)', $result->getColorAsString()); + + $result = ColorTransformer::colorToPixel(new Color(255, 255, 255, 170)); + $this->assertInstanceOf(ImagickPixel::class, $result); + $this->assertEquals('srgba(255,255,255,0.699992)', $result->getColorAsString()); + } +} diff --git a/tests/Drivers/Imagick/Decoders/HtmlColorNameDecoderTest.php b/tests/Drivers/Imagick/Decoders/HtmlColorNameDecoderTest.php index 4328f4b1..ba9790f6 100644 --- a/tests/Drivers/Imagick/Decoders/HtmlColorNameDecoderTest.php +++ b/tests/Drivers/Imagick/Decoders/HtmlColorNameDecoderTest.php @@ -2,7 +2,7 @@ namespace Intervention\Image\Tests\Drivers\Imagick\Decoders; -use Intervention\Image\Drivers\Imagick\Color; +use Intervention\Image\Colors\Rgb\Color; use Intervention\Image\Drivers\Imagick\Decoders\HtmlColorNameDecoder; use Intervention\Image\Tests\TestCase; diff --git a/tests/Drivers/Imagick/Decoders/RgbStringColorDecoderTest.php b/tests/Drivers/Imagick/Decoders/RgbStringColorDecoderTest.php index c3b6a52a..3029bc02 100644 --- a/tests/Drivers/Imagick/Decoders/RgbStringColorDecoderTest.php +++ b/tests/Drivers/Imagick/Decoders/RgbStringColorDecoderTest.php @@ -2,7 +2,8 @@ namespace Intervention\Image\Tests\Drivers\Imagick\Decoders; -use Intervention\Image\Drivers\Imagick\Color; +use Intervention\Image\Colors\Rgb\Color as RgbColor; +use Intervention\Image\Colors\Rgba\Color as RgbaColor; use Intervention\Image\Drivers\Imagick\Decoders\RgbStringColorDecoder; use Intervention\Image\Tests\TestCase; @@ -16,21 +17,15 @@ class RgbStringColorDecoderTest extends TestCase { $decoder = new RgbStringColorDecoder(); $color = $decoder->decode('rgb(181, 55, 23)'); - $this->assertInstanceOf(Color::class, $color); - $this->assertEquals(181, $color->red()); - $this->assertEquals(55, $color->green()); - $this->assertEquals(23, $color->blue()); - $this->assertEquals(1, $color->alpha()); + $this->assertInstanceOf(RgbColor::class, $color); + $this->assertEquals([181, 55, 23], $color->toArray()); } public function testDecodeRgba(): void { $decoder = new RgbStringColorDecoder(); - $color = $decoder->decode('rgba(181, 55, 23, 0.5)'); - $this->assertInstanceOf(Color::class, $color); - $this->assertEquals(181, $color->red()); - $this->assertEquals(55, $color->green()); - $this->assertEquals(23, $color->blue()); - $this->assertEquals(.5, $color->alpha()); + $color = $decoder->decode('rgba(181, 55, 23, 0.2)'); + $this->assertInstanceOf(RgbaColor::class, $color); + $this->assertEquals([181, 55, 23, 51], $color->toArray()); } } diff --git a/tests/Drivers/Imagick/Decoders/TransparentColorDecoderTest.php b/tests/Drivers/Imagick/Decoders/TransparentColorDecoderTest.php deleted file mode 100644 index 011947ad..00000000 --- a/tests/Drivers/Imagick/Decoders/TransparentColorDecoderTest.php +++ /dev/null @@ -1,25 +0,0 @@ -decode('transparent'); - $this->assertInstanceOf(Color::class, $color); - $this->assertEquals(0, $color->red()); - $this->assertEquals(0, $color->green()); - $this->assertEquals(0, $color->blue()); - $this->assertEquals(0, $color->alpha()); - } -}