From 9bca7b2dbd26641c8cba67ab7104fe31aecffbb0 Mon Sep 17 00:00:00 2001 From: Oliver Vogel Date: Fri, 1 Aug 2025 16:24:53 +0200 Subject: [PATCH] Add DriverInterface::handleImageInput() & handleColorInput() --- src/Drivers/AbstractDriver.php | 44 +++++++++ src/Drivers/Gd/AnimationFactory.php | 4 +- src/Drivers/Gd/Encoders/JpegEncoder.php | 2 +- .../Gd/Modifiers/DrawPixelModifier.php | 2 +- src/Drivers/Gd/Modifiers/FillModifier.php | 2 +- src/Drivers/Gd/Modifiers/PlaceModifier.php | 2 +- src/Drivers/Imagick/AnimationFactory.php | 4 +- src/Drivers/Imagick/Encoders/JpegEncoder.php | 2 +- .../Imagick/Modifiers/DrawPixelModifier.php | 2 +- .../Imagick/Modifiers/FillModifier.php | 2 +- .../Imagick/Modifiers/PlaceModifier.php | 2 +- .../Imagick/Modifiers/TextModifier.php | 4 +- src/Image.php | 4 +- src/ImageManager.php | 14 +-- src/InputHandler.php | 53 +++++++---- src/Interfaces/DriverInterface.php | 30 +++++++ src/Interfaces/ImageManagerInterface.php | 6 ++ src/Modifiers/AbstractDrawModifier.php | 8 +- src/Modifiers/BackgroundModifier.php | 2 +- src/Modifiers/ContainModifier.php | 2 +- src/Modifiers/CropModifier.php | 2 +- src/Modifiers/QuantizeColorsModifier.php | 4 +- src/Modifiers/ResizeCanvasModifier.php | 4 +- src/Modifiers/RotateModifier.php | 4 +- src/Modifiers/TextModifier.php | 4 +- tests/Unit/Drivers/Gd/DriverTest.php | 90 +++++++++++++++---- 26 files changed, 234 insertions(+), 65 deletions(-) diff --git a/src/Drivers/AbstractDriver.php b/src/Drivers/AbstractDriver.php index 408b8e8d..9a5046f7 100644 --- a/src/Drivers/AbstractDriver.php +++ b/src/Drivers/AbstractDriver.php @@ -60,6 +60,50 @@ abstract class AbstractDriver implements DriverInterface return InputHandler::withDecoders($decoders, $this)->handle($input); } + /** + * {@inheritdoc} + * + * @see DriverInterface::handleImageInput() + * + * @throws DriverException|DecoderException|NotSupportedException|RuntimeException + */ + public function handleImageInput(mixed $input, array $decoders = []): ImageInterface + { + $handler = count($decoders) ? + InputHandler::withDecoders($decoders, $this) : + InputHandler::withImageDecoders($this); + + $result = $handler->handle($input); + + if (!($result instanceof ImageInterface)) { + throw new DecoderException('Unable to decode input to instance of ImageInterface.'); + } + + return $result; + } + + /** + * {@inheritdoc} + * + * @see DriverInterface::handleColorInput() + * + * @throws DriverException|DecoderException|NotSupportedException|RuntimeException + */ + public function handleColorInput(mixed $input, array $decoders = []): ColorInterface + { + $handler = count($decoders) ? + InputHandler::withDecoders($decoders, $this) : + InputHandler::withColorDecoders($this); + + $result = $handler->handle($input); + + if (!($result instanceof ColorInterface)) { + throw new DecoderException('Unable to decode input to instance of ColorInterface.'); + } + + return $result; + } + /** * {@inheritdoc} * diff --git a/src/Drivers/Gd/AnimationFactory.php b/src/Drivers/Gd/AnimationFactory.php index b3e38ce6..bb06bfb4 100644 --- a/src/Drivers/Gd/AnimationFactory.php +++ b/src/Drivers/Gd/AnimationFactory.php @@ -6,6 +6,7 @@ namespace Intervention\Image\Drivers\Gd; use Intervention\Image\Exceptions\AnimationException; use Intervention\Image\Exceptions\DecoderException; +use Intervention\Image\Exceptions\RuntimeException; use Intervention\Image\Image; use Intervention\Image\Interfaces\AnimationFactoryInterface; use Intervention\Image\Interfaces\CoreInterface; @@ -24,11 +25,12 @@ class AnimationFactory implements AnimationFactoryInterface /** * @throws AnimationException * @throws DecoderException + * @throws RuntimeException */ public function add(mixed $source, float $delay = 1): self { $this->core->add( - $this->driver->handleInput($source)->core()->first()->setDelay($delay) + $this->driver->handleImageInput($source)->core()->first()->setDelay($delay) ); return $this; diff --git a/src/Drivers/Gd/Encoders/JpegEncoder.php b/src/Drivers/Gd/Encoders/JpegEncoder.php index d8fa473d..c72691b9 100644 --- a/src/Drivers/Gd/Encoders/JpegEncoder.php +++ b/src/Drivers/Gd/Encoders/JpegEncoder.php @@ -19,7 +19,7 @@ class JpegEncoder extends GenericJpegEncoder implements SpecializedInterface */ public function encode(ImageInterface $image): EncodedImage { - $backgroundColor = $this->driver()->handleInput( + $backgroundColor = $this->driver()->handleColorInput( $this->driver()->config()->backgroundColor ); diff --git a/src/Drivers/Gd/Modifiers/DrawPixelModifier.php b/src/Drivers/Gd/Modifiers/DrawPixelModifier.php index 9fc954cd..03347c74 100644 --- a/src/Drivers/Gd/Modifiers/DrawPixelModifier.php +++ b/src/Drivers/Gd/Modifiers/DrawPixelModifier.php @@ -18,7 +18,7 @@ class DrawPixelModifier extends GenericDrawPixelModifier implements SpecializedI public function apply(ImageInterface $image): ImageInterface { $color = $this->driver()->colorProcessor($image->colorspace())->colorToNative( - $this->driver()->handleInput($this->color) + $this->driver()->handleColorInput($this->color) ); foreach ($image as $frame) { diff --git a/src/Drivers/Gd/Modifiers/FillModifier.php b/src/Drivers/Gd/Modifiers/FillModifier.php index 412f8059..dc3824d9 100644 --- a/src/Drivers/Gd/Modifiers/FillModifier.php +++ b/src/Drivers/Gd/Modifiers/FillModifier.php @@ -38,7 +38,7 @@ class FillModifier extends GenericFillModifier implements SpecializedInterface private function color(ImageInterface $image): int { return $this->driver()->colorProcessor($image->colorspace())->colorToNative( - $this->driver()->handleInput($this->color) + $this->driver()->handleColorInput($this->color) ); } diff --git a/src/Drivers/Gd/Modifiers/PlaceModifier.php b/src/Drivers/Gd/Modifiers/PlaceModifier.php index d5c009bd..0ef55239 100644 --- a/src/Drivers/Gd/Modifiers/PlaceModifier.php +++ b/src/Drivers/Gd/Modifiers/PlaceModifier.php @@ -20,7 +20,7 @@ class PlaceModifier extends GenericPlaceModifier implements SpecializedInterface */ public function apply(ImageInterface $image): ImageInterface { - $watermark = $this->driver()->handleInput($this->element); + $watermark = $this->driver()->handleImageInput($this->element); $position = $this->position($image, $watermark); foreach ($image as $frame) { diff --git a/src/Drivers/Imagick/AnimationFactory.php b/src/Drivers/Imagick/AnimationFactory.php index 65f92ead..4dfc0003 100644 --- a/src/Drivers/Imagick/AnimationFactory.php +++ b/src/Drivers/Imagick/AnimationFactory.php @@ -7,6 +7,7 @@ namespace Intervention\Image\Drivers\Imagick; use Imagick; use Intervention\Image\Exceptions\AnimationException; use Intervention\Image\Exceptions\DecoderException; +use Intervention\Image\Exceptions\RuntimeException; use Intervention\Image\Image; use Intervention\Image\Interfaces\AnimationFactoryInterface; use Intervention\Image\Interfaces\DriverInterface; @@ -24,10 +25,11 @@ class AnimationFactory implements AnimationFactoryInterface /** * @throws AnimationException * @throws DecoderException + * @throws RuntimeException */ public function add(mixed $source, float $delay = 1): self { - $native = $this->driver->handleInput($source)->core()->native(); + $native = $this->driver->handleImageInput($source)->core()->native(); $native->setImageDelay(intval(round($delay * 100))); $this->imagick->addImage($native); diff --git a/src/Drivers/Imagick/Encoders/JpegEncoder.php b/src/Drivers/Imagick/Encoders/JpegEncoder.php index 0b4af267..8e5605d3 100644 --- a/src/Drivers/Imagick/Encoders/JpegEncoder.php +++ b/src/Drivers/Imagick/Encoders/JpegEncoder.php @@ -18,7 +18,7 @@ class JpegEncoder extends GenericJpegEncoder implements SpecializedInterface { $format = 'JPEG'; $compression = Imagick::COMPRESSION_JPEG; - $backgroundColor = $this->driver()->handleInput( + $backgroundColor = $this->driver()->handleColorInput( $this->driver()->config()->backgroundColor ); diff --git a/src/Drivers/Imagick/Modifiers/DrawPixelModifier.php b/src/Drivers/Imagick/Modifiers/DrawPixelModifier.php index e69ecc27..0a7341ba 100644 --- a/src/Drivers/Imagick/Modifiers/DrawPixelModifier.php +++ b/src/Drivers/Imagick/Modifiers/DrawPixelModifier.php @@ -14,7 +14,7 @@ class DrawPixelModifier extends GenericDrawPixelModifier implements SpecializedI public function apply(ImageInterface $image): ImageInterface { $color = $this->driver()->colorProcessor($image->colorspace())->colorToNative( - $this->driver()->handleInput($this->color) + $this->driver()->handleColorInput($this->color) ); $pixel = new ImagickDraw(); diff --git a/src/Drivers/Imagick/Modifiers/FillModifier.php b/src/Drivers/Imagick/Modifiers/FillModifier.php index 274745fa..93aba441 100644 --- a/src/Drivers/Imagick/Modifiers/FillModifier.php +++ b/src/Drivers/Imagick/Modifiers/FillModifier.php @@ -16,7 +16,7 @@ class FillModifier extends ModifiersFillModifier implements SpecializedInterface public function apply(ImageInterface $image): ImageInterface { $pixel = $this->driver()->colorProcessor($image->colorspace())->colorToNative( - $this->driver()->handleInput($this->color) + $this->driver()->handleColorInput($this->color) ); foreach ($image->core()->native() as $frame) { diff --git a/src/Drivers/Imagick/Modifiers/PlaceModifier.php b/src/Drivers/Imagick/Modifiers/PlaceModifier.php index 1bd2fec3..f4b82faf 100644 --- a/src/Drivers/Imagick/Modifiers/PlaceModifier.php +++ b/src/Drivers/Imagick/Modifiers/PlaceModifier.php @@ -13,7 +13,7 @@ class PlaceModifier extends GenericPlaceModifier implements SpecializedInterface { public function apply(ImageInterface $image): ImageInterface { - $watermark = $this->driver()->handleInput($this->element); + $watermark = $this->driver()->handleImageInput($this->element); $position = $this->position($image, $watermark); // set opacity of watermark diff --git a/src/Drivers/Imagick/Modifiers/TextModifier.php b/src/Drivers/Imagick/Modifiers/TextModifier.php index 69ff34ca..8eea5dae 100644 --- a/src/Drivers/Imagick/Modifiers/TextModifier.php +++ b/src/Drivers/Imagick/Modifiers/TextModifier.php @@ -59,7 +59,7 @@ class TextModifier extends GenericTextModifier implements SpecializedInterface */ private function imagickDrawText(ImageInterface $image, FontInterface $font): ImagickDraw { - $color = $this->driver()->handleInput($font->color()); + $color = $this->driver()->handleColorInput($font->color()); if ($font->hasStrokeEffect() && $color->isTransparent()) { throw new ColorException( @@ -87,7 +87,7 @@ class TextModifier extends GenericTextModifier implements SpecializedInterface return null; } - $color = $this->driver()->handleInput($font->strokeColor()); + $color = $this->driver()->handleColorInput($font->strokeColor()); if ($color->isTransparent()) { throw new ColorException( diff --git a/src/Image.php b/src/Image.php index 1f707b72..db19ecd9 100644 --- a/src/Image.php +++ b/src/Image.php @@ -407,7 +407,7 @@ final class Image implements ImageInterface */ public function backgroundColor(): ColorInterface { - return $this->driver()->handleInput( + return $this->driver()->handleColorInput( $this->driver()->config()->backgroundColor ); } @@ -420,7 +420,7 @@ final class Image implements ImageInterface public function setBackgroundColor(string|ColorInterface $color): ImageInterface { $this->driver()->config()->setOptions( - backgroundColor: $this->driver()->handleInput($color) + backgroundColor: $this->driver()->handleColorInput($color) ); return $this; diff --git a/src/ImageManager.php b/src/ImageManager.php index 9624832f..bc53f779 100644 --- a/src/ImageManager.php +++ b/src/ImageManager.php @@ -91,7 +91,7 @@ final class ImageManager implements ImageManagerInterface */ public function readPath(string $path): ImageInterface { - return $this->driver->handleInput($path, [FilePathImageDecoder::class]); + return $this->driver->handleImageInput($path, [FilePathImageDecoder::class]); } /** @@ -101,7 +101,7 @@ final class ImageManager implements ImageManagerInterface */ public function readBinary(string $data): ImageInterface { - return $this->driver->handleInput($data, [BinaryImageDecoder::class]); + return $this->driver->handleImageInput($data, [BinaryImageDecoder::class]); } /** @@ -111,7 +111,7 @@ final class ImageManager implements ImageManagerInterface */ public function readBase64(string $data): ImageInterface { - return $this->driver->handleInput($data, [Base64ImageDecoder::class]); + return $this->driver->handleImageInput($data, [Base64ImageDecoder::class]); } /** @@ -121,7 +121,7 @@ final class ImageManager implements ImageManagerInterface */ public function readDataUri(string $uri): ImageInterface { - return $this->driver->handleInput($uri, [DataUriImageDecoder::class]); + return $this->driver->handleImageInput($uri, [DataUriImageDecoder::class]); } /** @@ -131,7 +131,7 @@ final class ImageManager implements ImageManagerInterface */ public function readStream(mixed $stream): ImageInterface { - return $this->driver->handleInput($stream, [FilePointerImageDecoder::class]); + return $this->driver->handleImageInput($stream, [FilePointerImageDecoder::class]); } /** @@ -141,7 +141,7 @@ final class ImageManager implements ImageManagerInterface */ public function readSplFileInfo(SplFileInfo $file): ImageInterface { - return $this->driver->handleInput($file, [SplFileInfoImageDecoder::class]); + return $this->driver->handleImageInput($file, [SplFileInfoImageDecoder::class]); } /** @@ -151,7 +151,7 @@ final class ImageManager implements ImageManagerInterface */ public function read(mixed $input, string|array|DecoderInterface $decoders = []): ImageInterface { - return $this->driver->handleInput( + return $this->driver->handleImageInput( $input, match (true) { is_string($decoders), is_a($decoders, DecoderInterface::class) => [$decoders], diff --git a/src/InputHandler.php b/src/InputHandler.php index 0737d26b..1e13ba89 100644 --- a/src/InputHandler.php +++ b/src/InputHandler.php @@ -33,22 +33,9 @@ use Intervention\Image\Interfaces\InputHandlerInterface; class InputHandler implements InputHandlerInterface { - /** - * Decoder classnames in hierarchical order - * - * @var array - */ - protected array $decoders = [ + public const IMAGE_DECODERS = [ NativeObjectDecoder::class, ImageObjectDecoder::class, - ColorObjectDecoder::class, - RgbHexColorDecoder::class, - RgbStringColorDecoder::class, - CmykStringColorDecoder::class, - HsvStringColorDecoder::class, - HslStringColorDecoder::class, - TransparentColorDecoder::class, - HtmlColornameDecoder::class, FilePointerImageDecoder::class, FilePathImageDecoder::class, SplFileInfoImageDecoder::class, @@ -58,6 +45,24 @@ class InputHandler implements InputHandlerInterface EncodedImageObjectDecoder::class, ]; + public const COLOR_DECODERS = [ + ColorObjectDecoder::class, + RgbHexColorDecoder::class, + RgbStringColorDecoder::class, + CmykStringColorDecoder::class, + HsvStringColorDecoder::class, + HslStringColorDecoder::class, + TransparentColorDecoder::class, + HtmlColornameDecoder::class, + ]; + + /** + * Decoder classnames in hierarchical order + * + * @var array + */ + protected array $decoders = []; + /** * Driver with which the decoder classes are specialized */ @@ -71,12 +76,12 @@ class InputHandler implements InputHandlerInterface */ public function __construct(array $decoders = [], ?DriverInterface $driver = null) { - $this->decoders = count($decoders) ? $decoders : $this->decoders; + $this->decoders = count($decoders) ? $decoders : array_merge(self::COLOR_DECODERS, self::IMAGE_DECODERS); $this->driver = $driver; } /** - * Static factory method + * Static factory method to create input handler for both image and color handling * * @param array $decoders */ @@ -85,6 +90,22 @@ class InputHandler implements InputHandlerInterface return new self($decoders, $driver); } + /** + * Static factory method to create input handler for image handling + */ + public static function withImageDecoders(?DriverInterface $driver = null): self + { + return new self(self::IMAGE_DECODERS, $driver); + } + + /** + * Static factory method to create input handler for color handling + */ + public static function withColorDecoders(?DriverInterface $driver = null): self + { + return new self(self::COLOR_DECODERS, $driver); + } + /** * {@inheritdoc} * diff --git a/src/Interfaces/DriverInterface.php b/src/Interfaces/DriverInterface.php index e8468508..f99b91d7 100644 --- a/src/Interfaces/DriverInterface.php +++ b/src/Interfaces/DriverInterface.php @@ -67,6 +67,36 @@ interface DriverInterface */ public function handleInput(mixed $input, array $decoders = []): ImageInterface|ColorInterface; + /** + * Handle given image source by decoding it to ImageInterface + * + * Image sources can be as follows: + * + * - Path in filesystem + * - Raw binary image data + * - Base64 encoded image data + * - Data Uri + * - File Pointer resource + * - SplFileInfo object + * - Intervention Image Instance (Intervention\Image\Image) + * - Encoded Intervention Image (Intervention\Image\EncodedImage) + * - Driver-specific image (instance of GDImage or Imagick) + * + * @param array $decoders + * @throws DecoderException + * @throws RuntimeException + */ + public function handleImageInput(mixed $input, array $decoders = []): ImageInterface; + + /** + * Handle given image source by decoding it to ColorInterface + * + * @param array $decoders + * @throws DecoderException + * @throws RuntimeException + */ + public function handleColorInput(mixed $input, array $decoders = []): ColorInterface; + /** * Return color processor for the given colorspace */ diff --git a/src/Interfaces/ImageManagerInterface.php b/src/Interfaces/ImageManagerInterface.php index 1e798439..cf9e2a90 100644 --- a/src/Interfaces/ImageManagerInterface.php +++ b/src/Interfaces/ImageManagerInterface.php @@ -23,6 +23,7 @@ interface ImageManagerInterface * Create new image instance from given file path * * @throws DecoderException + * @throws RuntimeException */ public function readPath(string $path): ImageInterface; @@ -30,6 +31,7 @@ interface ImageManagerInterface * Create new image instance from given image binary data * * @throws DecoderException + * @throws RuntimeException */ public function readBinary(string $data): ImageInterface; @@ -37,6 +39,7 @@ interface ImageManagerInterface * Create new image instance from given base64 encoded image data * * @throws DecoderException + * @throws RuntimeException */ public function readBase64(string $data): ImageInterface; @@ -44,6 +47,7 @@ interface ImageManagerInterface * Create new image instance from given data uri encoded image data * * @throws DecoderException + * @throws RuntimeException */ public function readDataUri(string $uri): ImageInterface; @@ -51,6 +55,7 @@ interface ImageManagerInterface * Create new image instance from given image stream resource * * @throws DecoderException + * @throws RuntimeException */ public function readStream(mixed $stream): ImageInterface; @@ -58,6 +63,7 @@ interface ImageManagerInterface * Create new image instance from given SplFileInfo image object * * @throws DecoderException + * @throws RuntimeException */ public function readSplFileInfo(SplFileInfo $file): ImageInterface; diff --git a/src/Modifiers/AbstractDrawModifier.php b/src/Modifiers/AbstractDrawModifier.php index 123b1638..dcecd9e3 100644 --- a/src/Modifiers/AbstractDrawModifier.php +++ b/src/Modifiers/AbstractDrawModifier.php @@ -23,9 +23,9 @@ abstract class AbstractDrawModifier extends SpecializableModifier public function backgroundColor(): ColorInterface { try { - $color = $this->driver()->handleInput($this->drawable()->backgroundColor()); + $color = $this->driver()->handleColorInput($this->drawable()->backgroundColor()); } catch (DecoderException) { - return $this->driver()->handleInput('transparent'); + return $this->driver()->handleColorInput('transparent'); } return $color; @@ -37,9 +37,9 @@ abstract class AbstractDrawModifier extends SpecializableModifier public function borderColor(): ColorInterface { try { - $color = $this->driver()->handleInput($this->drawable()->borderColor()); + $color = $this->driver()->handleColorInput($this->drawable()->borderColor()); } catch (DecoderException) { - return $this->driver()->handleInput('transparent'); + return $this->driver()->handleColorInput('transparent'); } return $color; diff --git a/src/Modifiers/BackgroundModifier.php b/src/Modifiers/BackgroundModifier.php index 75007148..7a2ee217 100644 --- a/src/Modifiers/BackgroundModifier.php +++ b/src/Modifiers/BackgroundModifier.php @@ -36,7 +36,7 @@ class BackgroundModifier extends SpecializableModifier protected function backgroundColor(DriverInterface $driver): ColorInterface { // decode background color - $color = $driver->handleInput( + $color = $driver->handleColorInput( $this->color ?: $driver->config()->backgroundColor ); diff --git a/src/Modifiers/ContainModifier.php b/src/Modifiers/ContainModifier.php index dc20b5a3..60d0c847 100644 --- a/src/Modifiers/ContainModifier.php +++ b/src/Modifiers/ContainModifier.php @@ -54,6 +54,6 @@ class ContainModifier extends SpecializableModifier */ protected function backgroundColor(): ColorInterface { - return $this->driver()->handleInput($this->background ?? $this->driver()->config()->backgroundColor); + return $this->driver()->handleColorInput($this->background ?? $this->driver()->config()->backgroundColor); } } diff --git a/src/Modifiers/CropModifier.php b/src/Modifiers/CropModifier.php index 77d1b841..ef9738b4 100644 --- a/src/Modifiers/CropModifier.php +++ b/src/Modifiers/CropModifier.php @@ -51,6 +51,6 @@ class CropModifier extends SpecializableModifier */ protected function backgroundColor(): ColorInterface { - return $this->driver()->handleInput($this->background ?? $this->driver()->config()->backgroundColor); + return $this->driver()->handleColorInput($this->background ?? $this->driver()->config()->backgroundColor); } } diff --git a/src/Modifiers/QuantizeColorsModifier.php b/src/Modifiers/QuantizeColorsModifier.php index 2c5b49eb..b9fd64b2 100644 --- a/src/Modifiers/QuantizeColorsModifier.php +++ b/src/Modifiers/QuantizeColorsModifier.php @@ -29,6 +29,8 @@ class QuantizeColorsModifier extends SpecializableModifier */ protected function backgroundColor(): ColorInterface { - return $this->driver()->handleInput($this->background ?? $this->driver()->config()->backgroundColor); + return $this->driver()->handleColorInput( + $this->background ?? $this->driver()->config()->backgroundColor + ); } } diff --git a/src/Modifiers/ResizeCanvasModifier.php b/src/Modifiers/ResizeCanvasModifier.php index 7ff8fd11..52fa0385 100644 --- a/src/Modifiers/ResizeCanvasModifier.php +++ b/src/Modifiers/ResizeCanvasModifier.php @@ -56,6 +56,8 @@ class ResizeCanvasModifier extends SpecializableModifier */ protected function backgroundColor(): ColorInterface { - return $this->driver()->handleInput($this->background ?? $this->driver()->config()->backgroundColor); + return $this->driver()->handleColorInput( + $this->background ?? $this->driver()->config()->backgroundColor, + ); } } diff --git a/src/Modifiers/RotateModifier.php b/src/Modifiers/RotateModifier.php index 775c0eda..8172c8f8 100644 --- a/src/Modifiers/RotateModifier.php +++ b/src/Modifiers/RotateModifier.php @@ -31,6 +31,8 @@ class RotateModifier extends SpecializableModifier */ protected function backgroundColor(): ColorInterface { - return $this->driver()->handleInput($this->background ?? $this->driver()->config()->backgroundColor); + return $this->driver()->handleColorInput( + $this->background ?? $this->driver()->config()->backgroundColor, + ); } } diff --git a/src/Modifiers/TextModifier.php b/src/Modifiers/TextModifier.php index b48772ea..643ab89e 100644 --- a/src/Modifiers/TextModifier.php +++ b/src/Modifiers/TextModifier.php @@ -40,7 +40,7 @@ class TextModifier extends SpecializableModifier */ protected function textColor(): ColorInterface { - $color = $this->driver()->handleInput($this->font->color()); + $color = $this->driver()->handleColorInput($this->font->color()); if ($this->font->hasStrokeEffect() && $color->isTransparent()) { throw new ColorException( @@ -59,7 +59,7 @@ class TextModifier extends SpecializableModifier */ protected function strokeColor(): ColorInterface { - $color = $this->driver()->handleInput($this->font->strokeColor()); + $color = $this->driver()->handleColorInput($this->font->strokeColor()); if ($color->isTransparent()) { throw new ColorException( diff --git a/tests/Unit/Drivers/Gd/DriverTest.php b/tests/Unit/Drivers/Gd/DriverTest.php index 1b23ed2b..cfd07c12 100644 --- a/tests/Unit/Drivers/Gd/DriverTest.php +++ b/tests/Unit/Drivers/Gd/DriverTest.php @@ -15,12 +15,14 @@ use Intervention\Image\Drivers\Gd\Driver; use Intervention\Image\Drivers\Gd\Encoders\PngEncoder; use Intervention\Image\Drivers\Gd\Modifiers\ResizeModifier; use Intervention\Image\Encoders\PngEncoder as GenericPngEncoder; +use Intervention\Image\Exceptions\DecoderException; use Intervention\Image\Exceptions\NotSupportedException; use Intervention\Image\FileExtension; use Intervention\Image\Format; use Intervention\Image\Interfaces\AnalyzerInterface; use Intervention\Image\Interfaces\ColorInterface; use Intervention\Image\Interfaces\ColorProcessorInterface; +use Intervention\Image\Interfaces\DecoderInterface; use Intervention\Image\Interfaces\DriverInterface; use Intervention\Image\Interfaces\ImageInterface; use Intervention\Image\Interfaces\SpecializableInterface; @@ -69,32 +71,88 @@ final class DriverTest extends BaseTestCase $this->assertEquals(2, $image->count()); } - public function testHandleInputImage(): void + /** + * @param array $decoders + */ + #[DataProvider('handleImageInputDataProvider')] + #[DataProvider('handleColorInputDataProvider')] + public function testHandleInput(mixed $input, array $decoders, string $resultClassname): void { - $result = $this->driver->handleInput($this->getTestResourcePath('test.jpg')); - $this->assertInstanceOf(ImageInterface::class, $result); + $this->assertInstanceOf($resultClassname, $this->driver->handleInput($input, $decoders)); } - public function testHandleInputColor(): void + /** + * @param array $decoders + */ + #[DataProvider('handleImageInputDataProvider')] + public function testHandleImageInput(mixed $input, array $decoders, string $resultClassname): void { - $result = $this->driver->handleInput('ffffff'); - $this->assertInstanceOf(ColorInterface::class, $result); + $this->assertInstanceOf($resultClassname, $this->driver->handleImageInput($input, $decoders)); } - public function testHandleInputObjects(): void + /** + * @param array $decoders + */ + #[DataProvider('handleColorInputDataProvider')] + public function testHandleColorInput(mixed $input, array $decoders, string $resultClassname): void { - $result = $this->driver->handleInput('ffffff', [ - new HexColorDecoder() - ]); - $this->assertInstanceOf(ColorInterface::class, $result); + $this->assertInstanceOf($resultClassname, $this->driver->handleColorInput($input, $decoders)); } - public function testHandleInputClassnames(): void + /** + * @param array $decoders + */ + #[DataProvider('handleImageInputDataProvider')] + public function testHandleColorInputFail(mixed $input, array $decoders): void { - $result = $this->driver->handleInput('ffffff', [ - HexColorDecoder::class - ]); - $this->assertInstanceOf(ColorInterface::class, $result); + $this->expectException(DecoderException::class); + $this->driver->handleColorInput($input, $decoders); + } + + /** + * @param array $decoders + */ + #[DataProvider('handleColorInputDataProvider')] + public function testHandleImageInputFail(mixed $input, array $decoders): void + { + $this->expectException(DecoderException::class); + $this->driver->handleImageInput($input, $decoders); + } + + public static function handleImageInputDataProvider(): Generator + { + yield [ + self::getTestResourcePath('test.jpg'), + [], + ImageInterface::class, + ]; + + yield [ + self::getTestResourceData('test.jpg'), + [], + ImageInterface::class, + ]; + } + + public static function handleColorInputDataProvider(): Generator + { + yield [ + 'ffffff', + [], + ColorInterface::class, + ]; + + yield [ + 'ffffff', + [new HexColorDecoder()], + ColorInterface::class, + ]; + + yield [ + 'ffffff', + [HexColorDecoder::class], + ColorInterface::class, + ]; } public function testColorProcessor(): void