1
0
mirror of https://github.com/Intervention/image.git synced 2025-08-12 17:03:59 +02:00

Refactor checking for driver objects

This commit is contained in:
Oliver Vogel
2023-09-30 11:30:03 +02:00
parent 50f7ebce78
commit 25572c0ef9
18 changed files with 82 additions and 146 deletions

View File

@@ -4,11 +4,13 @@ namespace Intervention\Image\Drivers\Abstract;
use Intervention\Image\Interfaces\ColorInterface; use Intervention\Image\Interfaces\ColorInterface;
use Intervention\Image\Interfaces\FontInterface; use Intervention\Image\Interfaces\FontInterface;
use Intervention\Image\Traits\CanCheckType;
use Intervention\Image\Traits\CanHandleInput; use Intervention\Image\Traits\CanHandleInput;
abstract class AbstractFont implements FontInterface abstract class AbstractFont implements FontInterface
{ {
use CanHandleInput; use CanHandleInput;
use CanCheckType;
protected $size = 12; protected $size = 12;
protected $angle = 0; protected $angle = 0;

View File

@@ -5,10 +5,13 @@ namespace Intervention\Image\Drivers\Abstract;
use Intervention\Image\Geometry\Point; use Intervention\Image\Geometry\Point;
use Intervention\Image\Interfaces\FontInterface; use Intervention\Image\Interfaces\FontInterface;
use Intervention\Image\Interfaces\ModifierInterface; use Intervention\Image\Interfaces\ModifierInterface;
use Intervention\Image\Traits\CanCheckType;
use Intervention\Image\Typography\TextBlock; use Intervention\Image\Typography\TextBlock;
abstract class AbstractTextWriter implements ModifierInterface abstract class AbstractTextWriter implements ModifierInterface
{ {
use CanCheckType;
public function __construct( public function __construct(
protected Point $position, protected Point $position,
protected FontInterface $font, protected FontInterface $font,

View File

@@ -11,11 +11,13 @@ use Intervention\Image\Geometry\Rectangle;
use Intervention\Image\Interfaces\ColorInterface; use Intervention\Image\Interfaces\ColorInterface;
use Intervention\Image\Interfaces\DrawableInterface; use Intervention\Image\Interfaces\DrawableInterface;
use Intervention\Image\Interfaces\PointInterface; use Intervention\Image\Interfaces\PointInterface;
use Intervention\Image\Traits\CanCheckType;
use Intervention\Image\Traits\CanHandleInput; use Intervention\Image\Traits\CanHandleInput;
class AbstractDrawModifier class AbstractDrawModifier
{ {
use CanHandleInput; use CanHandleInput;
use CanCheckType;
public function __construct( public function __construct(
protected PointInterface $position, protected PointInterface $position,

View File

@@ -5,9 +5,12 @@ namespace Intervention\Image\Drivers\Abstract\Modifiers;
use Intervention\Image\Geometry\Rectangle; use Intervention\Image\Geometry\Rectangle;
use Intervention\Image\Interfaces\ImageInterface; use Intervention\Image\Interfaces\ImageInterface;
use Intervention\Image\Interfaces\SizeInterface; use Intervention\Image\Interfaces\SizeInterface;
use Intervention\Image\Traits\CanCheckType;
abstract class AbstractPadModifier abstract class AbstractPadModifier
{ {
use CanCheckType;
public function __construct( public function __construct(
protected int $width, protected int $width,
protected int $height, protected int $height,

View File

@@ -5,11 +5,13 @@ namespace Intervention\Image\Drivers\Abstract\Modifiers;
use Intervention\Image\Exceptions\DecoderException; use Intervention\Image\Exceptions\DecoderException;
use Intervention\Image\Exceptions\TypeException; use Intervention\Image\Exceptions\TypeException;
use Intervention\Image\Interfaces\ColorInterface; use Intervention\Image\Interfaces\ColorInterface;
use Intervention\Image\Traits\CanCheckType;
use Intervention\Image\Traits\CanHandleInput; use Intervention\Image\Traits\CanHandleInput;
abstract class AbstractRotateModifier abstract class AbstractRotateModifier
{ {
use CanHandleInput; use CanHandleInput;
use CanCheckType;
public function __construct(protected float $angle, protected $background) public function __construct(protected float $angle, protected $background)
{ {

View File

@@ -4,8 +4,6 @@ namespace Intervention\Image\Drivers\Gd\Modifiers;
use Intervention\Image\Drivers\Abstract\AbstractTextWriter; use Intervention\Image\Drivers\Abstract\AbstractTextWriter;
use Intervention\Image\Drivers\Gd\Font; use Intervention\Image\Drivers\Gd\Font;
use Intervention\Image\Exceptions\FontException;
use Intervention\Image\Interfaces\FontInterface;
use Intervention\Image\Interfaces\ImageInterface; use Intervention\Image\Interfaces\ImageInterface;
class TextWriter extends AbstractTextWriter class TextWriter extends AbstractTextWriter
@@ -13,30 +11,27 @@ class TextWriter extends AbstractTextWriter
public function apply(ImageInterface $image): ImageInterface public function apply(ImageInterface $image): ImageInterface
{ {
$lines = $this->getAlignedTextBlock(); $lines = $this->getAlignedTextBlock();
$font = $this->failIfNotClass($this->getFont(), Font::class);
foreach ($image as $frame) { foreach ($image as $frame) {
if ($this->font->hasFilename()) { if ($this->font->hasFilename()) {
foreach ($lines as $line) { foreach ($lines as $line) {
imagettftext( imagettftext(
$frame->getCore(), $frame->getCore(),
$this->getFont()->getSize(), $font->getSize(),
$this->getFont()->getAngle() * (-1), $font->getAngle() * (-1),
$line->getPosition()->getX(), $line->getPosition()->getX(),
$line->getPosition()->getY(), $line->getPosition()->getY(),
$this->getFont()->getColor()->toInt(), $font->getColor()->toInt(),
$this->getFont()->getFilename(), $font->getFilename(),
$line $line
); );
} }
// debug
// $lines = new TextBlock($this->text);
// $box = $lines->getBoundingBox($this->font, $this->position);
// imagepolygon($frame->getCore(), $box->toArray(), 0);
} else { } else {
foreach ($lines as $line) { foreach ($lines as $line) {
imagestring( imagestring(
$frame->getCore(), $frame->getCore(),
$this->getFont()->getGdFont(), $font->getGdFont(),
$line->getPosition()->getX(), $line->getPosition()->getX(),
$line->getPosition()->getY(), $line->getPosition()->getY(),
$line, $line,
@@ -48,12 +43,4 @@ class TextWriter extends AbstractTextWriter
return $image; return $image;
} }
protected function getFont(): FontInterface
{
if (!is_a($this->font, Font::class)) {
throw new FontException('Font is not compatible to current driver.');
}
return $this->font;
}
} }

View File

@@ -8,7 +8,6 @@ use Intervention\Image\Drivers\Abstract\AbstractFont;
use Intervention\Image\Exceptions\FontException; use Intervention\Image\Exceptions\FontException;
use Intervention\Image\Geometry\Polygon; use Intervention\Image\Geometry\Polygon;
use Intervention\Image\Geometry\Rectangle; use Intervention\Image\Geometry\Rectangle;
use Intervention\Image\Interfaces\ColorInterface;
class Font extends AbstractFont class Font extends AbstractFont
{ {
@@ -18,28 +17,19 @@ class Font extends AbstractFont
throw new FontException('No font file specified.'); throw new FontException('No font file specified.');
} }
$color = $this->failIfNotClass($this->getColor(), Color::class);
$draw = new ImagickDraw(); $draw = new ImagickDraw();
$draw->setStrokeAntialias(true); $draw->setStrokeAntialias(true);
$draw->setTextAntialias(true); $draw->setTextAntialias(true);
$draw->setFont($this->getFilename()); $draw->setFont($this->getFilename());
$draw->setFontSize($this->getSize()); $draw->setFontSize($this->getSize());
$draw->setFillColor($this->getColor()->getPixel()); $draw->setFillColor($color->getPixel());
$draw->setTextAlignment(Imagick::ALIGN_LEFT); $draw->setTextAlignment(Imagick::ALIGN_LEFT);
return $draw; return $draw;
} }
public function getColor(): ?ColorInterface
{
$color = parent::getColor();
if (!is_a($color, Color::class)) {
throw new FontException('Font is not compatible to current driver.');
}
return $color;
}
/** /**
* Calculate box size of current font * Calculate box size of current font
* *

View File

@@ -5,8 +5,6 @@ namespace Intervention\Image\Drivers\Imagick\Modifiers;
use ImagickDraw; use ImagickDraw;
use Intervention\Image\Drivers\Abstract\Modifiers\AbstractDrawModifier; use Intervention\Image\Drivers\Abstract\Modifiers\AbstractDrawModifier;
use Intervention\Image\Drivers\Imagick\Color; use Intervention\Image\Drivers\Imagick\Color;
use Intervention\Image\Exceptions\DecoderException;
use Intervention\Image\Interfaces\ColorInterface;
use Intervention\Image\Interfaces\ImageInterface; use Intervention\Image\Interfaces\ImageInterface;
use Intervention\Image\Interfaces\ModifierInterface; use Intervention\Image\Interfaces\ModifierInterface;
@@ -14,13 +12,16 @@ class DrawEllipseModifier extends AbstractDrawModifier implements ModifierInterf
{ {
public function apply(ImageInterface $image): ImageInterface public function apply(ImageInterface $image): ImageInterface
{ {
return $image->eachFrame(function ($frame) { $background_color = $this->failIfNotClass($this->getBackgroundColor(), Color::class);
$border_color = $this->failIfNotClass($this->getBorderColor(), Color::class);
return $image->eachFrame(function ($frame) use ($background_color, $border_color) {
$drawing = new ImagickDraw(); $drawing = new ImagickDraw();
$drawing->setFillColor($this->getBackgroundColor()->getPixel()); $drawing->setFillColor($background_color->getPixel());
if ($this->ellipse()->hasBorder()) { if ($this->ellipse()->hasBorder()) {
$drawing->setStrokeWidth($this->ellipse()->getBorderSize()); $drawing->setStrokeWidth($this->ellipse()->getBorderSize());
$drawing->setStrokeColor($this->getBorderColor()->getPixel()); $drawing->setStrokeColor($border_color->getPixel());
} }
$drawing->ellipse( $drawing->ellipse(
@@ -35,24 +36,4 @@ class DrawEllipseModifier extends AbstractDrawModifier implements ModifierInterf
$frame->getCore()->drawImage($drawing); $frame->getCore()->drawImage($drawing);
}); });
} }
protected function getBackgroundColor(): ColorInterface
{
$color = parent::getBackgroundColor();
if (!is_a($color, Color::class)) {
throw new DecoderException('Unable to decode background color.');
}
return $color;
}
protected function getBorderColor(): ColorInterface
{
$color = parent::getBorderColor();
if (!is_a($color, Color::class)) {
throw new DecoderException('Unable to decode border color.');
}
return $color;
}
} }

View File

@@ -4,6 +4,7 @@ namespace Intervention\Image\Drivers\Imagick\Modifiers;
use ImagickDraw; use ImagickDraw;
use Intervention\Image\Drivers\Abstract\Modifiers\AbstractDrawModifier; use Intervention\Image\Drivers\Abstract\Modifiers\AbstractDrawModifier;
use Intervention\Image\Drivers\Imagick\Color;
use Intervention\Image\Interfaces\ImageInterface; use Intervention\Image\Interfaces\ImageInterface;
use Intervention\Image\Interfaces\ModifierInterface; use Intervention\Image\Interfaces\ModifierInterface;
@@ -12,7 +13,8 @@ class DrawLineModifier extends AbstractDrawModifier implements ModifierInterface
public function apply(ImageInterface $image): ImageInterface public function apply(ImageInterface $image): ImageInterface
{ {
$drawing = new ImagickDraw(); $drawing = new ImagickDraw();
$drawing->setStrokeColor($this->getBackgroundColor()->getPixel()); $color = $this->failIfNotClass($this->getBackgroundColor(), Color::class);
$drawing->setStrokeColor($color->getPixel());
$drawing->setStrokeWidth($this->line()->getWidth()); $drawing->setStrokeWidth($this->line()->getWidth());
$drawing->line( $drawing->line(
$this->line()->getStart()->getX(), $this->line()->getStart()->getX(),

View File

@@ -4,15 +4,16 @@ namespace Intervention\Image\Drivers\Imagick\Modifiers;
use ImagickDraw; use ImagickDraw;
use Intervention\Image\Drivers\Imagick\Color; use Intervention\Image\Drivers\Imagick\Color;
use Intervention\Image\Exceptions\TypeException;
use Intervention\Image\Geometry\Point; use Intervention\Image\Geometry\Point;
use Intervention\Image\Interfaces\ImageInterface; use Intervention\Image\Interfaces\ImageInterface;
use Intervention\Image\Interfaces\ModifierInterface; use Intervention\Image\Interfaces\ModifierInterface;
use Intervention\Image\Traits\CanCheckType;
use Intervention\Image\Traits\CanHandleInput; use Intervention\Image\Traits\CanHandleInput;
class DrawPixelModifier implements ModifierInterface class DrawPixelModifier implements ModifierInterface
{ {
use CanHandleInput; use CanHandleInput;
use CanCheckType;
public function __construct(protected Point $position, protected mixed $color) public function __construct(protected Point $position, protected mixed $color)
{ {
@@ -21,7 +22,11 @@ class DrawPixelModifier implements ModifierInterface
public function apply(ImageInterface $image): ImageInterface public function apply(ImageInterface $image): ImageInterface
{ {
$color = $this->decodeColor(); $color = $this->failIfNotClass(
$this->handleInput($this->color),
Color::class,
);
$pixel = new ImagickDraw(); $pixel = new ImagickDraw();
$pixel->setFillColor($color->getPixel()); $pixel->setFillColor($color->getPixel());
$pixel->point($this->position->getX(), $this->position->getY()); $pixel->point($this->position->getX(), $this->position->getY());
@@ -30,15 +35,4 @@ class DrawPixelModifier implements ModifierInterface
$frame->getCore()->drawImage($pixel); $frame->getCore()->drawImage($pixel);
}); });
} }
private function decodeColor(): Color
{
$color = $this->handleInput($this->color);
if (!is_a($color, Color::class)) {
throw new TypeException('Color is not compatible to current driver.');
}
return $color;
}
} }

View File

@@ -5,7 +5,6 @@ namespace Intervention\Image\Drivers\Imagick\Modifiers;
use ImagickDraw; use ImagickDraw;
use Intervention\Image\Drivers\Abstract\Modifiers\AbstractDrawModifier; use Intervention\Image\Drivers\Abstract\Modifiers\AbstractDrawModifier;
use Intervention\Image\Drivers\Imagick\Color; use Intervention\Image\Drivers\Imagick\Color;
use Intervention\Image\Exceptions\TypeException;
use Intervention\Image\Interfaces\DrawableInterface; use Intervention\Image\Interfaces\DrawableInterface;
use Intervention\Image\Interfaces\ImageInterface; use Intervention\Image\Interfaces\ImageInterface;
use Intervention\Image\Interfaces\ModifierInterface; use Intervention\Image\Interfaces\ModifierInterface;
@@ -21,12 +20,15 @@ class DrawPolygonModifier extends AbstractDrawModifier implements ModifierInterf
public function apply(ImageInterface $image): ImageInterface public function apply(ImageInterface $image): ImageInterface
{ {
$drawing = new ImagickDraw(); $drawing = new ImagickDraw();
$background_color = $this->failIfNotClass($this->getBackgroundColor(), Color::class);
$border_color = $this->failIfNotClass($this->getBorderColor(), Color::class);
if ($this->polygon()->hasBackgroundColor()) { if ($this->polygon()->hasBackgroundColor()) {
$drawing->setFillColor($this->getBackgroundColor()->getPixel()); $drawing->setFillColor($background_color->getPixel());
} }
if ($this->polygon()->hasBorder()) { if ($this->polygon()->hasBorder()) {
$drawing->setStrokeColor($this->getBorderColor()->getPixel()); $drawing->setStrokeColor($border_color->getPixel());
$drawing->setStrokeWidth($this->polygon()->getBorderSize()); $drawing->setStrokeWidth($this->polygon()->getBorderSize());
} }
@@ -46,26 +48,4 @@ class DrawPolygonModifier extends AbstractDrawModifier implements ModifierInterf
return $points; return $points;
} }
protected function getBackgroundColor(): ?Color
{
$color = parent::getBackgroundColor();
if (!is_a($color, Color::class)) {
throw new TypeException('Color is not compatible to current driver.');
}
return $color;
}
protected function getBorderColor(): ?Color
{
$color = parent::getBorderColor();
if (!is_a($color, Color::class)) {
throw new TypeException('Color is not compatible to current driver.');
}
return $color;
}
} }

View File

@@ -5,7 +5,6 @@ namespace Intervention\Image\Drivers\Imagick\Modifiers;
use ImagickDraw; use ImagickDraw;
use Intervention\Image\Drivers\Abstract\Modifiers\AbstractDrawModifier; use Intervention\Image\Drivers\Abstract\Modifiers\AbstractDrawModifier;
use Intervention\Image\Drivers\Imagick\Color; use Intervention\Image\Drivers\Imagick\Color;
use Intervention\Image\Exceptions\DecoderException;
use Intervention\Image\Interfaces\ImageInterface; use Intervention\Image\Interfaces\ImageInterface;
use Intervention\Image\Interfaces\ModifierInterface; use Intervention\Image\Interfaces\ModifierInterface;
@@ -13,11 +12,14 @@ class DrawRectangleModifier extends AbstractDrawModifier implements ModifierInte
{ {
public function apply(ImageInterface $image): ImageInterface public function apply(ImageInterface $image): ImageInterface
{ {
// setup rectangle // setup
$drawing = new ImagickDraw(); $drawing = new ImagickDraw();
$drawing->setFillColor($this->getBackgroundColor()->getPixel()); $background_color = $this->failIfNotClass($this->getBackgroundColor(), Color::class);
$border_color = $this->failIfNotClass($this->getBorderColor(), Color::class);
$drawing->setFillColor($background_color->getPixel());
if ($this->rectangle()->hasBorder()) { if ($this->rectangle()->hasBorder()) {
$drawing->setStrokeColor($this->getBorderColor()->getPixel()); $drawing->setStrokeColor($border_color->getPixel());
$drawing->setStrokeWidth($this->rectangle()->getBorderSize()); $drawing->setStrokeWidth($this->rectangle()->getBorderSize());
} }
@@ -35,24 +37,4 @@ class DrawRectangleModifier extends AbstractDrawModifier implements ModifierInte
return $image; return $image;
} }
protected function getBackgroundColor(): Color
{
$color = parent::getBackgroundColor();
if (!is_a($color, Color::class)) {
throw new DecoderException('Unable to decode background color.');
}
return $color;
}
protected function getBorderColor(): Color
{
$color = parent::getBorderColor();
if (!is_a($color, Color::class)) {
throw new DecoderException('Unable to decode border color.');
}
return $color;
}
} }

View File

@@ -6,7 +6,6 @@ use Imagick;
use ImagickDraw; use ImagickDraw;
use Intervention\Image\Drivers\Abstract\Modifiers\AbstractPadModifier; use Intervention\Image\Drivers\Abstract\Modifiers\AbstractPadModifier;
use Intervention\Image\Drivers\Imagick\Color; use Intervention\Image\Drivers\Imagick\Color;
use Intervention\Image\Exceptions\DecoderException;
use Intervention\Image\Interfaces\ImageInterface; use Intervention\Image\Interfaces\ImageInterface;
use Intervention\Image\Interfaces\ModifierInterface; use Intervention\Image\Interfaces\ModifierInterface;
use Intervention\Image\Interfaces\SizeInterface; use Intervention\Image\Interfaces\SizeInterface;
@@ -22,11 +21,7 @@ class PadModifier extends AbstractPadModifier implements ModifierInterface
{ {
$resize = $this->getResizeSize($image); $resize = $this->getResizeSize($image);
$crop = $this->getCropSize($image); $crop = $this->getCropSize($image);
$background = $this->handleInput($this->background); $background = $this->failIfNotClass($this->handleInput($this->background), Color::class);
if (!is_a($background, Color::class)) {
throw new DecoderException('Unable to decode backgroud color.');
}
foreach ($image as $frame) { foreach ($image as $frame) {
// resize current core // resize current core

View File

@@ -4,7 +4,6 @@ namespace Intervention\Image\Drivers\Imagick\Modifiers;
use Intervention\Image\Drivers\Abstract\Modifiers\AbstractRotateModifier; use Intervention\Image\Drivers\Abstract\Modifiers\AbstractRotateModifier;
use Intervention\Image\Drivers\Imagick\Color; use Intervention\Image\Drivers\Imagick\Color;
use Intervention\Image\Exceptions\DecoderException;
use Intervention\Image\Interfaces\ImageInterface; use Intervention\Image\Interfaces\ImageInterface;
use Intervention\Image\Interfaces\ModifierInterface; use Intervention\Image\Interfaces\ModifierInterface;
@@ -12,10 +11,7 @@ class RotateModifier extends AbstractRotateModifier implements ModifierInterface
{ {
public function apply(ImageInterface $image): ImageInterface public function apply(ImageInterface $image): ImageInterface
{ {
$background = $this->backgroundColor(); $background = $this->failIfNotClass($this->backgroundColor(), Color::class);
if (!is_a($background, Color::class)) {
throw new DecoderException('Unable to decode given background color.');
}
foreach ($image as $frame) { foreach ($image as $frame) {
$frame->getCore()->rotateImage( $frame->getCore()->rotateImage(

View File

@@ -4,7 +4,6 @@ namespace Intervention\Image\Drivers\Imagick\Modifiers;
use Intervention\Image\Drivers\Abstract\AbstractTextWriter; use Intervention\Image\Drivers\Abstract\AbstractTextWriter;
use Intervention\Image\Drivers\Imagick\Font; use Intervention\Image\Drivers\Imagick\Font;
use Intervention\Image\Exceptions\FontException;
use Intervention\Image\Interfaces\ImageInterface; use Intervention\Image\Interfaces\ImageInterface;
class TextWriter extends AbstractTextWriter class TextWriter extends AbstractTextWriter
@@ -12,13 +11,15 @@ class TextWriter extends AbstractTextWriter
public function apply(ImageInterface $image): ImageInterface public function apply(ImageInterface $image): ImageInterface
{ {
$lines = $this->getAlignedTextBlock(); $lines = $this->getAlignedTextBlock();
$font = $this->failIfNotClass($this->getFont(), Font::class);
foreach ($image as $frame) { foreach ($image as $frame) {
foreach ($lines as $line) { foreach ($lines as $line) {
$frame->getCore()->annotateImage( $frame->getCore()->annotateImage(
$this->getFont()->toImagickDraw(), $font->toImagickDraw(),
$line->getPosition()->getX(), $line->getPosition()->getX(),
$line->getPosition()->getY(), $line->getPosition()->getY(),
$this->getFont()->getAngle(), $font->getAngle(),
$line $line
); );
} }
@@ -26,12 +27,4 @@ class TextWriter extends AbstractTextWriter
return $image; return $image;
} }
protected function getFont(): Font
{
if (!is_a($this->font, Font::class)) {
throw new FontException('Font is not compatible to current driver.');
}
return $this->font;
}
} }

View File

@@ -0,0 +1,17 @@
<?php
namespace Intervention\Image\Traits;
use Intervention\Image\Exceptions\TypeException;
trait CanCheckType
{
public function failIfNotClass(mixed $input, string $classname)
{
if (!is_object($input) || get_class($input) != $classname) {
throw new TypeException('Given input is not instance of ' . $classname);
}
return $input;
}
}

View File

@@ -2,6 +2,7 @@
namespace Intervention\Image\Traits; namespace Intervention\Image\Traits;
use Intervention\Image\Exceptions\DecoderException;
use Intervention\Image\Interfaces\ColorInterface; use Intervention\Image\Interfaces\ColorInterface;
use Intervention\Image\Interfaces\ImageInterface; use Intervention\Image\Interfaces\ImageInterface;
@@ -9,8 +10,14 @@ trait CanHandleInput
{ {
use CanResolveDriverClass; use CanResolveDriverClass;
public function handleInput($input): ImageInterface|ColorInterface public function handleInput($input, ?string $check_result_against_classname = null): ImageInterface|ColorInterface
{ {
return $this->resolveDriverClass('InputHandler')->handle($input); $result = $this->resolveDriverClass('InputHandler')->handle($input);
if (!is_null($check_result_against_classname) && get_class($result) != $check_result_against_classname) {
throw new DecoderException('Decoded result is not an instance of ' . $check_result_against_classname);
}
return $result;
} }
} }

View File

@@ -64,7 +64,7 @@ final class AbstractRotateModifierTest extends TestCase
return parent::backgroundColor(); return parent::backgroundColor();
} }
public function handleInput($input): ImageInterface|ColorInterface public function handleInput($input, ?string $check_result_against_classname = null): ImageInterface|ColorInterface
{ {
if ($this->background === 'bad value') { if ($this->background === 'bad value') {
throw new DecoderException(); throw new DecoderException();