1
0
mirror of https://github.com/Intervention/image.git synced 2025-08-23 22:12:51 +02:00

Add static color factory method

This commit is contained in:
Oliver Vogel
2023-10-21 15:15:56 +02:00
parent a1f75482e1
commit 3401fefa4f
4 changed files with 163 additions and 0 deletions

View File

@@ -7,6 +7,7 @@ use Intervention\Image\Colors\Rgb\Channels\Green;
use Intervention\Image\Colors\Rgb\Channels\Red; use Intervention\Image\Colors\Rgb\Channels\Red;
use Intervention\Image\Colors\Rgb\Channels\Alpha; use Intervention\Image\Colors\Rgb\Channels\Alpha;
use Intervention\Image\Colors\Traits\CanHandleChannels; use Intervention\Image\Colors\Traits\CanHandleChannels;
use Intervention\Image\Drivers\Abstract\AbstractInputHandler;
use Intervention\Image\Interfaces\ColorChannelInterface; use Intervention\Image\Interfaces\ColorChannelInterface;
use Intervention\Image\Interfaces\ColorInterface; use Intervention\Image\Interfaces\ColorInterface;
use Intervention\Image\Interfaces\ColorspaceInterface; use Intervention\Image\Interfaces\ColorspaceInterface;
@@ -15,8 +16,20 @@ class Color implements ColorInterface
{ {
use CanHandleChannels; use CanHandleChannels;
/**
* Color channels
*/
protected array $channels; protected array $channels;
/**
* Create new instance
*
* @param int $r
* @param int $g
* @param int $b
* @param int $a
* @return ColorInterface
*/
public function __construct(int $r, int $g, int $b, int $a = 255) public function __construct(int $r, int $g, int $b, int $a = 255)
{ {
$this->channels = [ $this->channels = [
@@ -27,26 +40,68 @@ class Color implements ColorInterface
]; ];
} }
/**
* {@inheritdoc}
*
* @see ColorInterface::create()
*/
public static function create(mixed $input): ColorInterface
{
return (new class ([
Decoders\HexColorDecoder::class,
Decoders\StringColorDecoder::class,
Decoders\TransparentColorDecoder::class,
Decoders\HtmlColornameDecoder::class,
]) extends AbstractInputHandler
{
})->handle($input);
}
/**
* Return the RGB red color channel
*
* @return ColorChannelInterface
*/
public function red(): ColorChannelInterface public function red(): ColorChannelInterface
{ {
return $this->channel(Red::class); return $this->channel(Red::class);
} }
/**
* Return the RGB green color channel
*
* @return ColorChannelInterface
*/
public function green(): ColorChannelInterface public function green(): ColorChannelInterface
{ {
return $this->channel(Green::class); return $this->channel(Green::class);
} }
/**
* Return the RGB blue color channel
*
* @return ColorChannelInterface
*/
public function blue(): ColorChannelInterface public function blue(): ColorChannelInterface
{ {
return $this->channel(Blue::class); return $this->channel(Blue::class);
} }
/**
* Return the colors alpha channel
*
* @return ColorChannelInterface
*/
public function alpha(): ColorChannelInterface public function alpha(): ColorChannelInterface
{ {
return $this->channel(Alpha::class); return $this->channel(Alpha::class);
} }
/**
* {@inheritdoc}
*
* @see ColorInterface::toArray()
*/
public function toArray(): array public function toArray(): array
{ {
return array_map(function (ColorChannelInterface $channel) { return array_map(function (ColorChannelInterface $channel) {
@@ -54,6 +109,11 @@ class Color implements ColorInterface
}, $this->channels()); }, $this->channels());
} }
/**
* {@inheritdoc}
*
* @see ColorInterface::toHex()
*/
public function toHex(string $prefix = ''): string public function toHex(string $prefix = ''): string
{ {
if ($this->isFullyOpaque()) { if ($this->isFullyOpaque()) {
@@ -76,6 +136,11 @@ class Color implements ColorInterface
); );
} }
/**
* {@inheritdoc}
*
* @see ColorInterface::convertTo()
*/
public function convertTo(string|ColorspaceInterface $colorspace): ColorInterface public function convertTo(string|ColorspaceInterface $colorspace): ColorInterface
{ {
$colorspace = match (true) { $colorspace = match (true) {
@@ -86,11 +151,21 @@ class Color implements ColorInterface
return $colorspace->convertColor($this); return $colorspace->convertColor($this);
} }
/**
* Determine if the current color is fully opaque
*
* @return bool
*/
public function isFullyOpaque(): bool public function isFullyOpaque(): bool
{ {
return $this->alpha()->value() === 255; return $this->alpha()->value() === 255;
} }
/**
* {@inheritdoc}
*
* @see ColorInterface::toString()
*/
public function toString(): string public function toString(): string
{ {
if ($this->isFullyOpaque()) { if ($this->isFullyOpaque()) {
@@ -111,6 +186,11 @@ class Color implements ColorInterface
); );
} }
/**
* {@inheritdoc}
*
* @see ColorInterface::isGreyscale()
*/
public function isGreyscale(): bool public function isGreyscale(): bool
{ {
$values = [$this->red()->value(), $this->green()->value(), $this->blue()->value()]; $values = [$this->red()->value(), $this->green()->value(), $this->blue()->value()];
@@ -118,6 +198,11 @@ class Color implements ColorInterface
return count(array_unique($values, SORT_REGULAR)) === 1; return count(array_unique($values, SORT_REGULAR)) === 1;
} }
/**
* {@inheritdoc}
*
* @see ColorInterface::__toString()
*/
public function __toString(): string public function __toString(): string
{ {
return $this->toString(); return $this->toString();

View File

@@ -14,6 +14,16 @@ abstract class AbstractInputHandler
*/ */
protected array $decoders = []; protected array $decoders = [];
/**
* Create new instance
*
* @param array $decoders
*/
public function __construct(array $decoders = [])
{
$this->decoders = count($decoders) ? $decoders : $this->decoders;
}
/** /**
* Stack the decoder array into a nested decoder object * Stack the decoder array into a nested decoder object
* *

View File

@@ -4,12 +4,69 @@ namespace Intervention\Image\Interfaces;
interface ColorInterface interface ColorInterface
{ {
/**
* Static color factory method that passed input to color decoding input handler
*
* @param mixed $input
* @return ColorInterface
* @throws \Intervention\Image\Exceptions\DecoderException
*/
public static function create(mixed $input): ColorInterface;
/**
* Cast color object to string
*
* @return string
*/
public function __toString(): string; public function __toString(): string;
/**
* Cast color object to string
*
* @return string
*/
public function toString(): string; public function toString(): string;
/**
* Cast color object to array
*
* @return array
*/
public function toArray(): array; public function toArray(): array;
/**
* Cast color object to hex encoded web color
*
* @return string
*/
public function toHex(): string; public function toHex(): string;
/**
* Return array of all color channels
*
* @return array
*/
public function channels(): array; public function channels(): array;
/**
* Retrieve the color channel by its classname
*
* @param string $classname
* @return ColorChannelInterface
*/
public function channel(string $classname): ColorChannelInterface; public function channel(string $classname): ColorChannelInterface;
/**
* Convert color to given colorspace
*
* @return ColorInterface
*/
public function convertTo(string|ColorspaceInterface $colorspace): ColorInterface; public function convertTo(string|ColorspaceInterface $colorspace): ColorInterface;
/**
* Determine if the current color is gray
*
* @return bool
*/
public function isGreyscale(): bool; public function isGreyscale(): bool;
} }

View File

@@ -23,6 +23,17 @@ class ColorTest extends TestCase
$this->assertInstanceOf(Color::class, $color); $this->assertInstanceOf(Color::class, $color);
} }
public function testCreate(): void
{
$color = Color::create('ccc');
$this->assertInstanceOf(Color::class, $color);
$this->assertEquals([204, 204, 204, 255], $color->toArray());
$color = Color::create('rgba(10, 20, 30, .2)');
$this->assertInstanceOf(Color::class, $color);
$this->assertEquals([10, 20, 30, 51], $color->toArray());
}
public function testChannels(): void public function testChannels(): void
{ {
$color = new Color(10, 20, 30); $color = new Color(10, 20, 30);