diff --git a/src/Colors/Cmyk/Color.php b/src/Colors/Cmyk/Color.php index 00c612fb..da5f8f36 100644 --- a/src/Colors/Cmyk/Color.php +++ b/src/Colors/Cmyk/Color.php @@ -91,7 +91,7 @@ class Color implements ColorInterface public function toString(): string { return sprintf( - 'cmyk(%d, %d, %d, %d)', + 'cmyk(%d%%, %d%%, %d%%, %d%%)', $this->cyan()->value(), $this->magenta()->value(), $this->yellow()->value(), diff --git a/src/Drivers/Imagick/Font.php b/src/Drivers/Imagick/Font.php index 5e612c25..abea0185 100644 --- a/src/Drivers/Imagick/Font.php +++ b/src/Drivers/Imagick/Font.php @@ -9,18 +9,19 @@ use Intervention\Image\Drivers\Imagick\Traits\CanHandleColors; use Intervention\Image\Exceptions\FontException; use Intervention\Image\Geometry\Polygon; use Intervention\Image\Geometry\Rectangle; +use Intervention\Image\Interfaces\ColorspaceInterface; class Font extends AbstractFont { use CanHandleColors; - public function toImagickDraw(): ImagickDraw + public function toImagickDraw(ColorspaceInterface $colorspace): ImagickDraw { if (!$this->hasFilename()) { throw new FontException('No font file specified.'); } - $color = $this->colorToPixel($this->getColor()); + $color = $this->colorToPixel($this->getColor(), $colorspace); $draw = new ImagickDraw(); $draw->setStrokeAntialias(true); diff --git a/src/Drivers/Imagick/Image.php b/src/Drivers/Imagick/Image.php index d04b8405..d8c3d0a3 100644 --- a/src/Drivers/Imagick/Image.php +++ b/src/Drivers/Imagick/Image.php @@ -23,14 +23,7 @@ class Image extends AbstractImage implements ImageInterface, Iterator public function __construct(protected Imagick $imagick) { - $this->colorspace = match ($imagick->getImageColorspace()) { - Imagick::COLORSPACE_RGB, Imagick::COLORSPACE_SRGB => new RgbColorspace(), - Imagick::COLORSPACE_CMYK => new CmykColorspace(), - default => function () use ($imagick) { - $imagick->transformImageColorspace(Imagick::COLORSPACE_SRGB); - return new RgbColorspace(); - } - }; + // } public function getImagick(): Imagick @@ -140,7 +133,7 @@ class Image extends AbstractImage implements ImageInterface, Iterator if ($frame = $this->getFrame($frame_key)) { return $this->colorFromPixel( $frame->getCore()->getImagePixelColor($x, $y), - $this->colorspace + $this->getColorspace() ); } diff --git a/src/Drivers/Imagick/Modifiers/DrawEllipseModifier.php b/src/Drivers/Imagick/Modifiers/DrawEllipseModifier.php index 0c3e53fc..acaee3aa 100644 --- a/src/Drivers/Imagick/Modifiers/DrawEllipseModifier.php +++ b/src/Drivers/Imagick/Modifiers/DrawEllipseModifier.php @@ -14,8 +14,9 @@ class DrawEllipseModifier extends AbstractDrawModifier implements ModifierInterf public function apply(ImageInterface $image): ImageInterface { - $background_color = $this->colorToPixel($this->getBackgroundColor()); - $border_color = $this->colorToPixel($this->getBorderColor()); + $colorspace = $image->getColorspace(); + $background_color = $this->colorToPixel($this->getBackgroundColor(), $colorspace); + $border_color = $this->colorToPixel($this->getBorderColor(), $colorspace); return $image->eachFrame(function ($frame) use ($background_color, $border_color) { $drawing = new ImagickDraw(); diff --git a/src/Drivers/Imagick/Modifiers/DrawLineModifier.php b/src/Drivers/Imagick/Modifiers/DrawLineModifier.php index 74fa9472..c5634869 100644 --- a/src/Drivers/Imagick/Modifiers/DrawLineModifier.php +++ b/src/Drivers/Imagick/Modifiers/DrawLineModifier.php @@ -17,7 +17,7 @@ class DrawLineModifier extends AbstractDrawModifier implements ModifierInterface $drawing = new ImagickDraw(); $drawing->setStrokeWidth($this->line()->getWidth()); $drawing->setStrokeColor( - $this->colorToPixel($this->getBackgroundColor()) + $this->colorToPixel($this->getBackgroundColor(), $image->getColorspace()) ); $drawing->line( diff --git a/src/Drivers/Imagick/Modifiers/DrawPixelModifier.php b/src/Drivers/Imagick/Modifiers/DrawPixelModifier.php index abeebb95..8651511c 100644 --- a/src/Drivers/Imagick/Modifiers/DrawPixelModifier.php +++ b/src/Drivers/Imagick/Modifiers/DrawPixelModifier.php @@ -30,7 +30,7 @@ class DrawPixelModifier implements ModifierInterface ); $pixel = new ImagickDraw(); - $pixel->setFillColor($this->colorToPixel($color)); + $pixel->setFillColor($this->colorToPixel($color, $image->getColorspace())); $pixel->point($this->position->getX(), $this->position->getY()); return $image->eachFrame(function ($frame) use ($pixel) { diff --git a/src/Drivers/Imagick/Modifiers/DrawPolygonModifier.php b/src/Drivers/Imagick/Modifiers/DrawPolygonModifier.php index 34634dbb..695c83dd 100644 --- a/src/Drivers/Imagick/Modifiers/DrawPolygonModifier.php +++ b/src/Drivers/Imagick/Modifiers/DrawPolygonModifier.php @@ -22,8 +22,9 @@ class DrawPolygonModifier extends AbstractDrawModifier implements ModifierInterf public function apply(ImageInterface $image): ImageInterface { $drawing = new ImagickDraw(); - $background_color = $this->colorToPixel($this->getBackgroundColor()); - $border_color = $this->colorToPixel($this->getBorderColor()); + $colorspace = $image->getColorspace(); + $background_color = $this->colorToPixel($this->getBackgroundColor(), $colorspace); + $border_color = $this->colorToPixel($this->getBorderColor(), $colorspace); if ($this->polygon()->hasBackgroundColor()) { $drawing->setFillColor($background_color); diff --git a/src/Drivers/Imagick/Modifiers/DrawRectangleModifier.php b/src/Drivers/Imagick/Modifiers/DrawRectangleModifier.php index 60d225d3..2f0c81ad 100644 --- a/src/Drivers/Imagick/Modifiers/DrawRectangleModifier.php +++ b/src/Drivers/Imagick/Modifiers/DrawRectangleModifier.php @@ -15,8 +15,9 @@ class DrawRectangleModifier extends AbstractDrawModifier implements ModifierInte public function apply(ImageInterface $image): ImageInterface { $drawing = new ImagickDraw(); - $background_color = $this->colorToPixel($this->getBackgroundColor()); - $border_color = $this->colorToPixel($this->getBorderColor()); + $colorspace = $image->getColorspace(); + $background_color = $this->colorToPixel($this->getBackgroundColor(), $colorspace); + $border_color = $this->colorToPixel($this->getBorderColor(), $colorspace); $drawing->setFillColor($background_color); if ($this->rectangle()->hasBorder()) { diff --git a/src/Drivers/Imagick/Modifiers/FillModifier.php b/src/Drivers/Imagick/Modifiers/FillModifier.php index c78f06ba..24fd77a3 100644 --- a/src/Drivers/Imagick/Modifiers/FillModifier.php +++ b/src/Drivers/Imagick/Modifiers/FillModifier.php @@ -25,7 +25,8 @@ class FillModifier implements ModifierInterface public function apply(ImageInterface $image): ImageInterface { - $pixel = $this->colorToPixel($this->color); + $pixel = $this->colorToPixel($this->color, $image->getColorspace()); + foreach ($image as $frame) { if ($this->hasPosition()) { $this->floodFillWithColor($frame, $pixel); diff --git a/src/Drivers/Imagick/Modifiers/PadModifier.php b/src/Drivers/Imagick/Modifiers/PadModifier.php index fbfcbd23..b447737a 100644 --- a/src/Drivers/Imagick/Modifiers/PadModifier.php +++ b/src/Drivers/Imagick/Modifiers/PadModifier.php @@ -61,7 +61,7 @@ class PadModifier extends AbstractPadModifier implements ModifierInterface // draw background color on canvas $draw = new ImagickDraw(); - $draw->setFillColor($this->colorToPixel($background)); + $draw->setFillColor($this->colorToPixel($background, $canvas->getColorspace())); $draw->rectangle(0, 0, $canvas->getImageWidth(), $canvas->getImageHeight()); $canvas->drawImage($draw); diff --git a/src/Drivers/Imagick/Modifiers/RotateModifier.php b/src/Drivers/Imagick/Modifiers/RotateModifier.php index e178f31c..44e5ebad 100644 --- a/src/Drivers/Imagick/Modifiers/RotateModifier.php +++ b/src/Drivers/Imagick/Modifiers/RotateModifier.php @@ -15,7 +15,7 @@ class RotateModifier extends AbstractRotateModifier implements ModifierInterface { foreach ($image as $frame) { $frame->getCore()->rotateImage( - $this->colorToPixel($this->backgroundColor()), + $this->colorToPixel($this->backgroundColor(), $image->getColorspace()), $this->rotationAngle() ); } diff --git a/src/Drivers/Imagick/Modifiers/TextWriter.php b/src/Drivers/Imagick/Modifiers/TextWriter.php index 4bf3af51..0d345ed7 100644 --- a/src/Drivers/Imagick/Modifiers/TextWriter.php +++ b/src/Drivers/Imagick/Modifiers/TextWriter.php @@ -16,7 +16,7 @@ class TextWriter extends AbstractTextWriter foreach ($image as $frame) { foreach ($lines as $line) { $frame->getCore()->annotateImage( - $font->toImagickDraw(), + $font->toImagickDraw($image->getColorspace()), $line->getPosition()->getX(), $line->getPosition()->getY(), $font->getAngle(), diff --git a/src/Drivers/Imagick/Traits/CanHandleColors.php b/src/Drivers/Imagick/Traits/CanHandleColors.php index af6770b7..6b248128 100644 --- a/src/Drivers/Imagick/Traits/CanHandleColors.php +++ b/src/Drivers/Imagick/Traits/CanHandleColors.php @@ -4,7 +4,17 @@ namespace Intervention\Image\Drivers\Imagick\Traits; use Imagick; use ImagickPixel; +use Intervention\Image\Colors\Cmyk\Channels\Cyan; +use Intervention\Image\Colors\Cmyk\Channels\Key; +use Intervention\Image\Colors\Cmyk\Channels\Magenta; +use Intervention\Image\Colors\Cmyk\Channels\Yellow; use Intervention\Image\Colors\Cmyk\Colorspace as CmykColorspace; +use Intervention\Image\Colors\Cmyk\Color as CmykColor; +use Intervention\Image\Colors\Rgb\Color as RgbColor; +use Intervention\Image\Colors\Rgb\Channels\Alpha; +use Intervention\Image\Colors\Rgb\Channels\Blue; +use Intervention\Image\Colors\Rgb\Channels\Green; +use Intervention\Image\Colors\Rgb\Channels\Red; use Intervention\Image\Interfaces\ColorInterface; use Intervention\Image\Interfaces\ColorspaceInterface; @@ -41,8 +51,27 @@ trait CanHandleColors * @param ColorInterface $color * @return ImagickPixel */ - public function colorToPixel(ColorInterface $color): ImagickPixel + public function colorToPixel(ColorInterface $color, ColorspaceInterface $colorspace): ImagickPixel { - return new ImagickPixel($color->toString()); + $pixel = new ImagickPixel(); + $color = $color->convertTo($colorspace); + + switch (get_class($color)) { + case CmykColor::class: + $pixel->setColorValue(Imagick::COLOR_CYAN, $color->channel(Cyan::class)->normalize()); + $pixel->setColorValue(Imagick::COLOR_MAGENTA, $color->channel(Magenta::class)->normalize()); + $pixel->setColorValue(Imagick::COLOR_YELLOW, $color->channel(Yellow::class)->normalize()); + $pixel->setColorValue(Imagick::COLOR_BLACK, $color->channel(Key::class)->normalize()); + break; + + case RgbColor::class: + $pixel->setColorValue(Imagick::COLOR_RED, $color->channel(Red::class)->normalize()); + $pixel->setColorValue(Imagick::COLOR_GREEN, $color->channel(Green::class)->normalize()); + $pixel->setColorValue(Imagick::COLOR_BLUE, $color->channel(Blue::class)->normalize()); + $pixel->setColorValue(Imagick::COLOR_ALPHA, $color->channel(Alpha::class)->normalize()); + break; + } + + return $pixel; } } diff --git a/src/Drivers/Imagick/Traits/CanReadColors.php b/src/Drivers/Imagick/Traits/CanReadColors.php deleted file mode 100644 index aba65d76..00000000 --- a/src/Drivers/Imagick/Traits/CanReadColors.php +++ /dev/null @@ -1,14 +0,0 @@ -toString()); - } -} diff --git a/tests/Colors/Cmyk/ColorTest.php b/tests/Colors/Cmyk/ColorTest.php index 5dd59c28..f90673e6 100644 --- a/tests/Colors/Cmyk/ColorTest.php +++ b/tests/Colors/Cmyk/ColorTest.php @@ -64,6 +64,6 @@ class ColorTest extends TestCase public function testToString(): void { $color = new Color(100, 50, 20, 0); - $this->assertEquals('cmyk(100, 50, 20, 0)', (string) $color); + $this->assertEquals('cmyk(100%, 50%, 20%, 0%)', (string) $color); } } diff --git a/tests/Drivers/Imagick/Traits/CanHandleColorsTest.php b/tests/Drivers/Imagick/Traits/CanHandleColorsTest.php new file mode 100644 index 00000000..eaf36170 --- /dev/null +++ b/tests/Drivers/Imagick/Traits/CanHandleColorsTest.php @@ -0,0 +1,58 @@ +getAnonymousTrait() + ->colorFromPixel(new ImagickPixel(), new RgbColorspace()); + $this->assertInstanceOf(RgbColor::class, $result); + + $result = $this->getAnonymousTrait() + ->colorFromPixel(new ImagickPixel('rgba(10, 20, 30, .2)'), new RgbColorspace()); + $this->assertInstanceOf(RgbColor::class, $result); + $this->assertEquals([10, 20, 30, 51], $result->toArray()); + + $result = $this->getAnonymousTrait() + ->colorFromPixel(new ImagickPixel('cmyk(10%, 20%, 30%, 40%)'), new CmykColorspace()); + $this->assertInstanceOf(CmykColor::class, $result); + $this->assertEquals([10, 20, 30, 40], $result->toArray()); + } + + public function testColorToPixel(): void + { + $result = $this->getAnonymousTrait()->colorToPixel(new RgbColor(10, 20, 30), new RgbColorspace()); + $this->assertInstanceOf(ImagickPixel::class, $result); + $this->assertEquals('srgb(10,20,30)', $result->getColorAsString()); + + $result = $this->getAnonymousTrait()->colorToPixel(new CmykColor(100, 50, 25, 0), new CmykColorspace()); + $this->assertInstanceOf(ImagickPixel::class, $result); + $this->assertEquals(1, $result->getColorValue(Imagick::COLOR_CYAN)); + $this->assertEquals(.5, round($result->getColorValue(Imagick::COLOR_MAGENTA), 2)); + $this->assertEquals(.25, round($result->getColorValue(Imagick::COLOR_YELLOW), 2)); + $this->assertEquals(0, $result->getColorValue(Imagick::COLOR_BLACK)); + } +}