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

Replace color implementation in FillModifiers

This commit is contained in:
Oliver Vogel
2023-10-15 11:29:33 +02:00
parent dbbcded7a4
commit 56ab8b1ea7
40 changed files with 550 additions and 227 deletions

View File

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

View File

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

View File

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

View File

@@ -0,0 +1,34 @@
<?php
namespace Intervention\Image\Colors\Cmyk;
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');
}
return static::fromString($value);
}
public static function fromString(string $input): Color
{
// cmyk(100%, 100%, 100%, 100%)
$pattern = '/^cmyk\((?P<c>[0-9\.]+)%?, ?(?P<m>[0-9\.]+)%?, ?(?P<y>[0-9\.]+)%?, ?(?P<k>[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');
}
}

28
src/Colors/Parser.php Normal file
View File

@@ -0,0 +1,28 @@
<?php
namespace Intervention\Image\Colors;
use Intervention\Image\Exceptions\ColorException;
use Intervention\Image\Interfaces\ColorInterface;
class Parser
{
protected static $parsers = [
Rgb\Parser::class,
Rgba\Parser::class,
Cmyk\Parser::class,
];
public static function parse(mixed $value): ColorInterface
{
foreach (static::$parsers as $parser) {
try {
return forward_static_call([$parser, 'parse'], $value);
} catch (ColorException $e) {
# move on...
}
}
throw new ColorException('Unable to parse color');
}
}

View File

@@ -42,4 +42,14 @@ class Red implements ColorChannelInterface
return $value;
}
public function toString(): string
{
return (string) $this->value();
}
public function __toString(): string
{
return $this->toString();
}
}

View File

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

View File

@@ -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<hex>[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<r>[0-9]{1,3}), ?(?P<g>[0-9]{1,3}), ?(?P<b>[0-9]{1,3})\)$/';
// rgb(255, 255, 255)
$pattern = '/^s?rgb\((?P<r>[0-9]{1,3}), ?(?P<g>[0-9]{1,3}), ?(?P<b>[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<r>[0-9\.]+)%, ?(?P<g>[0-9\.]+)%, ?(?P<b>[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

View File

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

View File

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

View File

@@ -38,18 +38,31 @@ class Parser extends RgbParser
public static function fromString(string $input): Color
{
$pattern = '/^rgba\((?P<r>[0-9]{1,3}), *(?P<g>[0-9]{1,3}), *(?P<b>[0-9]{1,3}), *(?P<a>((1|0))?(\.[0-9]+)?)\)$/';
// rgba(255, 255, 255, 1.0)
$pattern = '/^s?rgba\((?P<r>[0-9]{1,3}), *(?P<g>[0-9]{1,3}), *(?P<b>[0-9]{1,3}), *(?P<a>((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<r>[0-9\.]+)%, ?(?P<g>[0-9\.]+)%, ?(?P<b>[0-9\.]+)%, ?(?P<a>[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');
}
}

View File

@@ -1,50 +0,0 @@
<?php
namespace Intervention\Image\Drivers\Gd;
use Intervention\Image\Drivers\Abstract\AbstractColor;
use Intervention\Image\Interfaces\ColorInterface;
class Color extends AbstractColor implements ColorInterface
{
public function __construct(protected int $value = 0)
{
//
}
public function red(): int
{
return $this->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;
}
}

View File

@@ -0,0 +1,61 @@
<?php
namespace Intervention\Image\Drivers\Gd;
use Intervention\Image\Interfaces\ColorInterface;
use Intervention\Image\Colors\Rgba\Color;
class ColorTransformer
{
/**
* Transforms GD Library integer color value to RGBA color object
*
* @param int $value
* @return Color
*/
public static function colorFromInteger(int $value): Color
{
$a = ($value >> 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);
}
}

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,61 +0,0 @@
<?php
namespace Intervention\Image\Drivers\Imagick;
use Imagick;
use ImagickPixel;
use Intervention\Image\Drivers\Abstract\AbstractColor;
use Intervention\Image\Interfaces\ColorInterface;
class Color extends AbstractColor implements ColorInterface
{
public function __construct(protected ImagickPixel $pixel)
{
//
}
public function getPixel(): ImagickPixel
{
return $this->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);
}
}

View File

@@ -0,0 +1,32 @@
<?php
namespace Intervention\Image\Drivers\Imagick;
use ImagickPixel;
use Intervention\Image\Colors\Parser;
use Intervention\Image\Interfaces\ColorInterface;
class ColorTransformer
{
/**
* Transforms ImagickPixel to own color object
*
* @param int $value
* @return ColorInterface
*/
public static function colorFromPixel(ImagickPixel $pixel): ColorInterface
{
return Parser::parse($pixel->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());
}
}

View File

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

View File

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

View File

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

View File

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

View File

@@ -0,0 +1,14 @@
<?php
namespace Intervention\Image\Drivers\Imagick\Traits;
use ImagickPixel;
use Intervention\Image\Interfaces\ColorInterface;
trait CanReadColors
{
public function colorToPixel(ColorInterface $color): ImagickPixel
{
return new ImagickPixel($color->toString());
}
}

View File

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

View File

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

View File

@@ -0,0 +1,32 @@
<?php
namespace Intervention\Image\Tests\Colors\Cmyk;
use Intervention\Image\Colors\Cmyk\Color;
use Intervention\Image\Colors\Cmyk\Parser;
use Intervention\Image\Tests\TestCase;
/**
* @requires extension gd
* @covers \Intervention\Image\Colors\Cmyk\Parser
*/
class ParserTest extends TestCase
{
public function testParse(): void
{
$color = Parser::fromString('cmyk(100, 0, 0, 0)');
$this->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());
}
}

View File

@@ -0,0 +1,47 @@
<?php
namespace Intervention\Image\Tests\Colors;
use Intervention\Image\Colors\Cmyk\Color as CmykColor;
use Intervention\Image\Colors\Rgb\Color as RgbColor;
use Intervention\Image\Colors\Rgba\Color as RgbaColor;
use Intervention\Image\Colors\Parser;
use Intervention\Image\Tests\TestCase;
/**
* @requires extension gd
* @covers \Intervention\Image\Colors\Parser
*/
class ParserTest extends TestCase
{
public function testParse(): void
{
$color = Parser::parse('ccc');
$this->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());
}
}

View File

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

View File

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

View File

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

View File

@@ -0,0 +1,30 @@
<?php
namespace Intervention\Image\Tests\Drivers\Gd;
use Intervention\Image\Colors\Rgba\Color;
use Intervention\Image\Drivers\Gd\ColorTransformer;
use Intervention\Image\Tests\TestCase;
class ColorTransformerTest extends TestCase
{
public function testFromInteger(): void
{
$result = ColorTransformer::colorFromInteger(850736919);
$this->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);
}
}

View File

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

View File

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

View File

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

View File

@@ -1,25 +0,0 @@
<?php
namespace Intervention\Image\Tests\Drivers\Gd\Decoders;
use Intervention\Image\Drivers\Gd\Color;
use Intervention\Image\Drivers\Gd\Decoders\TransparentColorDecoder;
use Intervention\Image\Tests\TestCase;
/**
* @requires extension gd
* @covers \Intervention\Image\Drivers\Gd\Decoders\TransparentColorDecoder
*/
class TransparentColorDecoderTest extends TestCase
{
public function testDecode(): void
{
$decoder = new TransparentColorDecoder();
$color = $decoder->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());
}
}

View File

@@ -0,0 +1,37 @@
<?php
namespace Intervention\Image\Tests\Drivers\Imagick;
use ImagickPixel;
use Intervention\Image\Colors\Rgba\Color;
use Intervention\Image\Drivers\Imagick\ColorTransformer;
use Intervention\Image\Tests\TestCase;
class ColorTransformerTest extends TestCase
{
public function testFromPixel(): void
{
$result = ColorTransformer::colorFromPixel(new ImagickPixel('rgba(181, 55, 23, .6)'));
$this->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());
}
}

View File

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

View File

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

View File

@@ -1,25 +0,0 @@
<?php
namespace Intervention\Image\Tests\Drivers\Imagick\Decoders;
use Intervention\Image\Drivers\Imagick\Color;
use Intervention\Image\Drivers\Imagick\Decoders\TransparentColorDecoder;
use Intervention\Image\Tests\TestCase;
/**
* @requires extension imagick
* @covers \Intervention\Image\Drivers\Imagick\Decoders\TransparentColorDecoder
*/
class TransparentColorDecoderTest extends TestCase
{
public function testDecode(): void
{
$decoder = new TransparentColorDecoder();
$color = $decoder->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());
}
}