From 1148c841478ea146506659b6bcd1f1c1db041fb5 Mon Sep 17 00:00:00 2001 From: Oliver Vogel Date: Sun, 31 Dec 2023 17:26:41 +0100 Subject: [PATCH 01/11] Add interface for driver specializing objects --- src/Drivers/AbstractDriver.php | 11 +++-- src/Drivers/DriverSpecialized.php | 54 +++++++++++++++++++++++ src/Drivers/DriverSpecializedAnalyzer.php | 24 +--------- src/Drivers/DriverSpecializedEncoder.php | 25 +---------- src/Drivers/DriverSpecializedModifier.php | 36 +-------------- src/Image.php | 6 +-- src/Interfaces/DriverInterface.php | 2 +- src/Interfaces/SpecializedInterface.php | 29 ++++++++++++ 8 files changed, 97 insertions(+), 90 deletions(-) create mode 100644 src/Drivers/DriverSpecialized.php create mode 100644 src/Interfaces/SpecializedInterface.php diff --git a/src/Drivers/AbstractDriver.php b/src/Drivers/AbstractDriver.php index 723d6e05..e92851a5 100644 --- a/src/Drivers/AbstractDriver.php +++ b/src/Drivers/AbstractDriver.php @@ -23,7 +23,7 @@ public function __construct() * @return object * @throws NotSupportedException */ - public function resolve(object $input): object + public function specialize(object $input): object { if ($this->isExternal($input)) { return $input; @@ -31,15 +31,18 @@ public function resolve(object $input): object $driver_namespace = (new ReflectionClass($this))->getNamespaceName(); $class_path = substr(get_class($input), strlen("Intervention\\Image\\")); - $specialized = $driver_namespace . "\\" . $class_path; + $classname = $driver_namespace . "\\" . $class_path; - if (! class_exists($specialized)) { + if (!class_exists($classname)) { throw new NotSupportedException( "Class '" . $class_path . "' is not supported by " . $this->id() . " driver." ); } - return new $specialized($input, $this); + return forward_static_call([ + $classname, + 'buildSpecialized' + ], $input, $this); } /** diff --git a/src/Drivers/DriverSpecialized.php b/src/Drivers/DriverSpecialized.php new file mode 100644 index 00000000..5adb9ad4 --- /dev/null +++ b/src/Drivers/DriverSpecialized.php @@ -0,0 +1,54 @@ +generic = $generic; + $specialized->driver = $driver; + + return $specialized; + } + + public function driver(): DriverInterface + { + return $this->driver; + } + + public function generic(): object + { + return $this->generic; + } + + /** + * Magic method to read attributes of underlying modifier + * + * @param string $name + * @return mixed + */ + public function __get(string $name): mixed + { + return $this->generic->$name; + } + + /** + * Magic method to call methods of underlying modifier + * + * @param string $name + * @param array $arguments + * @return mixed + */ + public function __call(string $name, array $arguments): mixed + { + return $this->generic->$name(...$arguments); + } +} diff --git a/src/Drivers/DriverSpecializedAnalyzer.php b/src/Drivers/DriverSpecializedAnalyzer.php index 9f69f7d1..2dcc4a81 100644 --- a/src/Drivers/DriverSpecializedAnalyzer.php +++ b/src/Drivers/DriverSpecializedAnalyzer.php @@ -3,29 +3,7 @@ namespace Intervention\Image\Drivers; use Intervention\Image\Interfaces\AnalyzerInterface; -use Intervention\Image\Interfaces\DriverInterface; -abstract class DriverSpecializedAnalyzer implements AnalyzerInterface +abstract class DriverSpecializedAnalyzer extends DriverSpecialized implements AnalyzerInterface { - public function __construct( - protected AnalyzerInterface $analyzer, - protected DriverInterface $driver - ) { - } - - public function driver(): DriverInterface - { - return $this->driver; - } - - /** - * Magic method to read attributes of underlying analyzer - * - * @param string $name - * @return mixed - */ - public function __get(string $name): mixed - { - return $this->analyzer->$name; - } } diff --git a/src/Drivers/DriverSpecializedEncoder.php b/src/Drivers/DriverSpecializedEncoder.php index 4c98da8b..038ccd7f 100644 --- a/src/Drivers/DriverSpecializedEncoder.php +++ b/src/Drivers/DriverSpecializedEncoder.php @@ -2,33 +2,10 @@ namespace Intervention\Image\Drivers; -use Intervention\Image\Interfaces\DriverInterface; use Intervention\Image\Interfaces\EncoderInterface; -abstract class DriverSpecializedEncoder implements EncoderInterface +abstract class DriverSpecializedEncoder extends DriverSpecialized implements EncoderInterface { - public function __construct( - protected EncoderInterface $encoder, - protected DriverInterface $driver - ) { - } - - public function driver(): DriverInterface - { - return $this->driver; - } - - /** - * Magic method to read attributes of underlying encoder - * - * @param string $name - * @return mixed - */ - public function __get(string $name): mixed - { - return $this->encoder->$name; - } - /** * Get return value of callback through output buffer * diff --git a/src/Drivers/DriverSpecializedModifier.php b/src/Drivers/DriverSpecializedModifier.php index 8f71a3b8..8c910f1c 100644 --- a/src/Drivers/DriverSpecializedModifier.php +++ b/src/Drivers/DriverSpecializedModifier.php @@ -2,42 +2,8 @@ namespace Intervention\Image\Drivers; -use Intervention\Image\Interfaces\DriverInterface; use Intervention\Image\Interfaces\ModifierInterface; -abstract class DriverSpecializedModifier implements ModifierInterface +abstract class DriverSpecializedModifier extends DriverSpecialized implements ModifierInterface { - public function __construct( - protected ModifierInterface $modifier, - protected DriverInterface $driver - ) { - } - - public function driver(): DriverInterface - { - return $this->driver; - } - - /** - * Magic method to read attributes of underlying modifier - * - * @param string $name - * @return mixed - */ - public function __get(string $name): mixed - { - return $this->modifier->$name; - } - - /** - * Magic method to call methods of underlying modifier - * - * @param string $name - * @param array $arguments - * @return mixed - */ - public function __call(string $name, array $arguments): mixed - { - return $this->modifier->$name(...$arguments); - } } diff --git a/src/Image.php b/src/Image.php index 72ea50bd..b571ca44 100644 --- a/src/Image.php +++ b/src/Image.php @@ -229,7 +229,7 @@ public function exif(?string $query = null): mixed */ public function modify(ModifierInterface $modifier): ImageInterface { - return $this->driver->resolve($modifier)->apply($this); + return $this->driver->specialize($modifier)->apply($this); } /** @@ -239,7 +239,7 @@ public function modify(ModifierInterface $modifier): ImageInterface */ public function analyze(AnalyzerInterface $analyzer): mixed { - return $this->driver->resolve($analyzer)->analyze($this); + return $this->driver->specialize($analyzer)->analyze($this); } /** @@ -249,7 +249,7 @@ public function analyze(AnalyzerInterface $analyzer): mixed */ public function encode(EncoderInterface $encoder = new AutoEncoder()): EncodedImage { - return $this->driver->resolve($encoder)->encode($this); + return $this->driver->specialize($encoder)->encode($this); } /** diff --git a/src/Interfaces/DriverInterface.php b/src/Interfaces/DriverInterface.php index 232291b6..675ced87 100644 --- a/src/Interfaces/DriverInterface.php +++ b/src/Interfaces/DriverInterface.php @@ -17,7 +17,7 @@ public function id(): string; * @param object $input * @return object */ - public function resolve(object $input): object; + public function specialize(object $input): object; /** * Create new image instance with the current driver in given dimensions diff --git a/src/Interfaces/SpecializedInterface.php b/src/Interfaces/SpecializedInterface.php new file mode 100644 index 00000000..c01b06f2 --- /dev/null +++ b/src/Interfaces/SpecializedInterface.php @@ -0,0 +1,29 @@ + Date: Sun, 31 Dec 2023 17:50:46 +0100 Subject: [PATCH 02/11] Remove DriverSpecializedAnalyzer & DriverSpecializedModifier --- src/Drivers/AbstractDrawModifier.php | 3 +- src/Drivers/AbstractDriver.php | 8 +++-- src/Drivers/AbstractTextModifier.php | 3 +- src/Drivers/DriverSpecializedAnalyzer.php | 9 ------ src/Drivers/DriverSpecializedModifier.php | 9 ------ .../Gd/Analyzers/ColorspaceAnalyzer.php | 5 ++-- src/Drivers/Gd/Analyzers/HeightAnalyzer.php | 5 ++-- .../Gd/Analyzers/PixelColorAnalyzer.php | 5 ++-- .../Gd/Analyzers/ResolutionAnalyzer.php | 5 ++-- src/Drivers/Gd/Analyzers/WidthAnalyzer.php | 5 ++-- src/Drivers/Gd/Modifiers/BlurModifier.php | 5 ++-- .../Gd/Modifiers/BrightnessModifier.php | 5 ++-- src/Drivers/Gd/Modifiers/ColorizeModifier.php | 5 ++-- .../Gd/Modifiers/ColorspaceModifier.php | 5 ++-- src/Drivers/Gd/Modifiers/ContrastModifier.php | 5 ++-- .../Gd/Modifiers/DrawPixelModifier.php | 5 ++-- src/Drivers/Gd/Modifiers/FillModifier.php | 5 ++-- src/Drivers/Gd/Modifiers/FlipModifier.php | 5 ++-- src/Drivers/Gd/Modifiers/FlopModifier.php | 5 ++-- src/Drivers/Gd/Modifiers/GammaModifier.php | 5 ++-- .../Gd/Modifiers/GreyscaleModifier.php | 5 ++-- src/Drivers/Gd/Modifiers/InvertModifier.php | 5 ++-- src/Drivers/Gd/Modifiers/PixelateModifier.php | 5 ++-- src/Drivers/Gd/Modifiers/PlaceModifier.php | 5 ++-- src/Drivers/Gd/Modifiers/ProfileModifier.php | 5 ++-- .../Gd/Modifiers/ProfileRemovalModifier.php | 5 ++-- .../Gd/Modifiers/RemoveAnimationModifier.php | 5 ++-- .../Gd/Modifiers/ResolutionModifier.php | 5 ++-- src/Drivers/Gd/Modifiers/SharpenModifier.php | 5 ++-- src/Drivers/Gd/SpecializedModifier.php | 5 ++-- .../Imagick/Analyzers/ColorspaceAnalyzer.php | 5 ++-- .../Imagick/Analyzers/HeightAnalyzer.php | 5 ++-- .../Imagick/Analyzers/PixelColorAnalyzer.php | 5 ++-- .../Imagick/Analyzers/ProfileAnalyzer.php | 5 ++-- .../Imagick/Analyzers/ResolutionAnalyzer.php | 5 ++-- .../Imagick/Analyzers/WidthAnalyzer.php | 5 ++-- .../Imagick/Modifiers/BlurModifier.php | 5 ++-- .../Imagick/Modifiers/BrightnessModifier.php | 5 ++-- .../Imagick/Modifiers/ColorizeModifier.php | 5 ++-- .../Imagick/Modifiers/ColorspaceModifier.php | 5 ++-- .../Imagick/Modifiers/ContainModifier.php | 5 ++-- .../Imagick/Modifiers/ContrastModifier.php | 5 ++-- .../Imagick/Modifiers/CoverModifier.php | 5 ++-- .../Imagick/Modifiers/CropModifier.php | 5 ++-- .../Imagick/Modifiers/DrawPixelModifier.php | 5 ++-- .../Imagick/Modifiers/FillModifier.php | 5 ++-- .../Imagick/Modifiers/FlipModifier.php | 5 ++-- .../Imagick/Modifiers/FlopModifier.php | 5 ++-- .../Imagick/Modifiers/GammaModifier.php | 5 ++-- .../Imagick/Modifiers/GreyscaleModifier.php | 5 ++-- .../Imagick/Modifiers/InvertModifier.php | 5 ++-- .../Imagick/Modifiers/PixelateModifier.php | 5 ++-- .../Imagick/Modifiers/PlaceModifier.php | 5 ++-- .../Imagick/Modifiers/ProfileModifier.php | 5 ++-- .../Modifiers/ProfileRemovalModifier.php | 5 ++-- .../Modifiers/QuantizeColorsModifier.php | 5 ++-- .../Modifiers/RemoveAnimationModifier.php | 5 ++-- .../Modifiers/ResizeCanvasModifier.php | 5 ++-- .../Imagick/Modifiers/ResizeModifier.php | 5 ++-- .../Imagick/Modifiers/ResolutionModifier.php | 5 ++-- .../Imagick/Modifiers/RotateModifier.php | 5 ++-- .../Imagick/Modifiers/SharpenModifier.php | 5 ++-- src/Interfaces/DriverInterface.php | 4 +-- .../Drivers/DriverSpecializedAnalyzerTest.php | 29 ------------------- 64 files changed, 183 insertions(+), 167 deletions(-) delete mode 100644 src/Drivers/DriverSpecializedAnalyzer.php delete mode 100644 src/Drivers/DriverSpecializedModifier.php delete mode 100644 tests/Drivers/DriverSpecializedAnalyzerTest.php diff --git a/src/Drivers/AbstractDrawModifier.php b/src/Drivers/AbstractDrawModifier.php index a75d499b..a563f8df 100644 --- a/src/Drivers/AbstractDrawModifier.php +++ b/src/Drivers/AbstractDrawModifier.php @@ -5,12 +5,13 @@ use Intervention\Image\Exceptions\DecoderException; use Intervention\Image\Interfaces\ColorInterface; use Intervention\Image\Interfaces\DrawableInterface; +use Intervention\Image\Interfaces\ModifierInterface; use Intervention\Image\Interfaces\PointInterface; /** * @property DrawableInterface $drawable */ -abstract class AbstractDrawModifier extends DriverSpecializedModifier +abstract class AbstractDrawModifier extends DriverSpecialized implements ModifierInterface { public function position(): PointInterface { diff --git a/src/Drivers/AbstractDriver.php b/src/Drivers/AbstractDriver.php index e92851a5..5fc26e15 100644 --- a/src/Drivers/AbstractDriver.php +++ b/src/Drivers/AbstractDriver.php @@ -5,7 +5,11 @@ use Intervention\Image\Analyzers\AbstractAnalyzer; use Intervention\Image\Encoders\AbstractEncoder; use Intervention\Image\Exceptions\NotSupportedException; +use Intervention\Image\Interfaces\AnalyzerInterface; +use Intervention\Image\Interfaces\DecoderInterface; use Intervention\Image\Interfaces\DriverInterface; +use Intervention\Image\Interfaces\EncoderInterface; +use Intervention\Image\Interfaces\ModifierInterface; use Intervention\Image\Modifiers\AbstractModifier; use ReflectionClass; @@ -20,10 +24,10 @@ public function __construct() * Return a specialized version for the current driver of the given object * * @param object $input - * @return object + * @return ModifierInterface|AnalyzerInterface|EncoderInterface|DecoderInterface * @throws NotSupportedException */ - public function specialize(object $input): object + public function specialize(object $input): ModifierInterface|AnalyzerInterface|EncoderInterface|DecoderInterface { if ($this->isExternal($input)) { return $input; diff --git a/src/Drivers/AbstractTextModifier.php b/src/Drivers/AbstractTextModifier.php index 01c9af0c..f0691c7d 100644 --- a/src/Drivers/AbstractTextModifier.php +++ b/src/Drivers/AbstractTextModifier.php @@ -6,13 +6,14 @@ use Intervention\Image\Geometry\Polygon; use Intervention\Image\Geometry\Rectangle; use Intervention\Image\Interfaces\FontInterface; +use Intervention\Image\Interfaces\ModifierInterface; use Intervention\Image\Typography\TextBlock; use Intervention\Image\Typography\Line; /** * @property FontInterface $font */ -abstract class AbstractTextModifier extends DriverSpecializedModifier +abstract class AbstractTextModifier extends DriverSpecialized implements ModifierInterface { abstract protected function boxSize(string $text): Polygon; diff --git a/src/Drivers/DriverSpecializedAnalyzer.php b/src/Drivers/DriverSpecializedAnalyzer.php deleted file mode 100644 index 2dcc4a81..00000000 --- a/src/Drivers/DriverSpecializedAnalyzer.php +++ /dev/null @@ -1,9 +0,0 @@ - Imagick::COLORSPACE_SRGB, diff --git a/src/Drivers/Imagick/Modifiers/ContainModifier.php b/src/Drivers/Imagick/Modifiers/ContainModifier.php index a39eea4a..d80445ee 100644 --- a/src/Drivers/Imagick/Modifiers/ContainModifier.php +++ b/src/Drivers/Imagick/Modifiers/ContainModifier.php @@ -4,8 +4,9 @@ use ImagickDraw; use ImagickPixel; -use Intervention\Image\Drivers\DriverSpecializedModifier; +use Intervention\Image\Drivers\DriverSpecialized; use Intervention\Image\Interfaces\ImageInterface; +use Intervention\Image\Interfaces\ModifierInterface; use Intervention\Image\Interfaces\SizeInterface; /** @@ -16,7 +17,7 @@ * @property mixed $background * @property string $position */ -class ContainModifier extends DriverSpecializedModifier +class ContainModifier extends DriverSpecialized implements ModifierInterface { public function apply(ImageInterface $image): ImageInterface { diff --git a/src/Drivers/Imagick/Modifiers/ContrastModifier.php b/src/Drivers/Imagick/Modifiers/ContrastModifier.php index d5e38d74..17a0a6e2 100644 --- a/src/Drivers/Imagick/Modifiers/ContrastModifier.php +++ b/src/Drivers/Imagick/Modifiers/ContrastModifier.php @@ -2,13 +2,14 @@ namespace Intervention\Image\Drivers\Imagick\Modifiers; -use Intervention\Image\Drivers\DriverSpecializedModifier; +use Intervention\Image\Drivers\DriverSpecialized; use Intervention\Image\Interfaces\ImageInterface; +use Intervention\Image\Interfaces\ModifierInterface; /** * @property int $level */ -class ContrastModifier extends DriverSpecializedModifier +class ContrastModifier extends DriverSpecialized implements ModifierInterface { public function apply(ImageInterface $image): ImageInterface { diff --git a/src/Drivers/Imagick/Modifiers/CoverModifier.php b/src/Drivers/Imagick/Modifiers/CoverModifier.php index 8e5c09f1..e484681e 100644 --- a/src/Drivers/Imagick/Modifiers/CoverModifier.php +++ b/src/Drivers/Imagick/Modifiers/CoverModifier.php @@ -2,15 +2,16 @@ namespace Intervention\Image\Drivers\Imagick\Modifiers; -use Intervention\Image\Drivers\DriverSpecializedModifier; +use Intervention\Image\Drivers\DriverSpecialized; use Intervention\Image\Interfaces\ImageInterface; +use Intervention\Image\Interfaces\ModifierInterface; use Intervention\Image\Interfaces\SizeInterface; /** * @method SizeInterface getResizeSize(ImageInterface $image) * @method SizeInterface getCropSize(ImageInterface $image) */ -class CoverModifier extends DriverSpecializedModifier +class CoverModifier extends DriverSpecialized implements ModifierInterface { public function apply(ImageInterface $image): ImageInterface { diff --git a/src/Drivers/Imagick/Modifiers/CropModifier.php b/src/Drivers/Imagick/Modifiers/CropModifier.php index a4becc1b..5e87b4cd 100644 --- a/src/Drivers/Imagick/Modifiers/CropModifier.php +++ b/src/Drivers/Imagick/Modifiers/CropModifier.php @@ -2,8 +2,9 @@ namespace Intervention\Image\Drivers\Imagick\Modifiers; -use Intervention\Image\Drivers\DriverSpecializedModifier; +use Intervention\Image\Drivers\DriverSpecialized; use Intervention\Image\Interfaces\ImageInterface; +use Intervention\Image\Interfaces\ModifierInterface; use Intervention\Image\Interfaces\SizeInterface; /** @@ -11,7 +12,7 @@ * @property int $offset_x * @property int $offset_y */ -class CropModifier extends DriverSpecializedModifier +class CropModifier extends DriverSpecialized implements ModifierInterface { public function apply(ImageInterface $image): ImageInterface { diff --git a/src/Drivers/Imagick/Modifiers/DrawPixelModifier.php b/src/Drivers/Imagick/Modifiers/DrawPixelModifier.php index 982a0f74..f4689aef 100644 --- a/src/Drivers/Imagick/Modifiers/DrawPixelModifier.php +++ b/src/Drivers/Imagick/Modifiers/DrawPixelModifier.php @@ -3,15 +3,16 @@ namespace Intervention\Image\Drivers\Imagick\Modifiers; use ImagickDraw; -use Intervention\Image\Drivers\DriverSpecializedModifier; +use Intervention\Image\Drivers\DriverSpecialized; use Intervention\Image\Interfaces\ImageInterface; +use Intervention\Image\Interfaces\ModifierInterface; use Intervention\Image\Interfaces\PointInterface; /** * @property PointInterface $position * @property mixed $color */ -class DrawPixelModifier extends DriverSpecializedModifier +class DrawPixelModifier extends DriverSpecialized implements ModifierInterface { public function apply(ImageInterface $image): ImageInterface { diff --git a/src/Drivers/Imagick/Modifiers/FillModifier.php b/src/Drivers/Imagick/Modifiers/FillModifier.php index d33d9746..8c9354ae 100644 --- a/src/Drivers/Imagick/Modifiers/FillModifier.php +++ b/src/Drivers/Imagick/Modifiers/FillModifier.php @@ -5,17 +5,18 @@ use Imagick; use ImagickDraw; use ImagickPixel; -use Intervention\Image\Drivers\DriverSpecializedModifier; +use Intervention\Image\Drivers\DriverSpecialized; use Intervention\Image\Drivers\Imagick\Frame; use Intervention\Image\Interfaces\ImageInterface; use Intervention\Image\Geometry\Point; +use Intervention\Image\Interfaces\ModifierInterface; /** * @method bool hasPosition() * @property mixed $color * @property null|Point $position */ -class FillModifier extends DriverSpecializedModifier +class FillModifier extends DriverSpecialized implements ModifierInterface { public function apply(ImageInterface $image): ImageInterface { diff --git a/src/Drivers/Imagick/Modifiers/FlipModifier.php b/src/Drivers/Imagick/Modifiers/FlipModifier.php index e9a6bcc9..0f8d568c 100644 --- a/src/Drivers/Imagick/Modifiers/FlipModifier.php +++ b/src/Drivers/Imagick/Modifiers/FlipModifier.php @@ -2,10 +2,11 @@ namespace Intervention\Image\Drivers\Imagick\Modifiers; -use Intervention\Image\Drivers\DriverSpecializedModifier; +use Intervention\Image\Drivers\DriverSpecialized; use Intervention\Image\Interfaces\ImageInterface; +use Intervention\Image\Interfaces\ModifierInterface; -class FlipModifier extends DriverSpecializedModifier +class FlipModifier extends DriverSpecialized implements ModifierInterface { public function apply(ImageInterface $image): ImageInterface { diff --git a/src/Drivers/Imagick/Modifiers/FlopModifier.php b/src/Drivers/Imagick/Modifiers/FlopModifier.php index 33827476..0df097ec 100644 --- a/src/Drivers/Imagick/Modifiers/FlopModifier.php +++ b/src/Drivers/Imagick/Modifiers/FlopModifier.php @@ -2,10 +2,11 @@ namespace Intervention\Image\Drivers\Imagick\Modifiers; -use Intervention\Image\Drivers\DriverSpecializedModifier; +use Intervention\Image\Drivers\DriverSpecialized; use Intervention\Image\Interfaces\ImageInterface; +use Intervention\Image\Interfaces\ModifierInterface; -class FlopModifier extends DriverSpecializedModifier +class FlopModifier extends DriverSpecialized implements ModifierInterface { public function apply(ImageInterface $image): ImageInterface { diff --git a/src/Drivers/Imagick/Modifiers/GammaModifier.php b/src/Drivers/Imagick/Modifiers/GammaModifier.php index 548d3007..8edef4a6 100644 --- a/src/Drivers/Imagick/Modifiers/GammaModifier.php +++ b/src/Drivers/Imagick/Modifiers/GammaModifier.php @@ -2,13 +2,14 @@ namespace Intervention\Image\Drivers\Imagick\Modifiers; -use Intervention\Image\Drivers\DriverSpecializedModifier; +use Intervention\Image\Drivers\DriverSpecialized; use Intervention\Image\Interfaces\ImageInterface; +use Intervention\Image\Interfaces\ModifierInterface; /** * @property float $gamma */ -class GammaModifier extends DriverSpecializedModifier +class GammaModifier extends DriverSpecialized implements ModifierInterface { public function apply(ImageInterface $image): ImageInterface { diff --git a/src/Drivers/Imagick/Modifiers/GreyscaleModifier.php b/src/Drivers/Imagick/Modifiers/GreyscaleModifier.php index d12c1e3b..db2762c8 100644 --- a/src/Drivers/Imagick/Modifiers/GreyscaleModifier.php +++ b/src/Drivers/Imagick/Modifiers/GreyscaleModifier.php @@ -2,10 +2,11 @@ namespace Intervention\Image\Drivers\Imagick\Modifiers; -use Intervention\Image\Drivers\DriverSpecializedModifier; +use Intervention\Image\Drivers\DriverSpecialized; use Intervention\Image\Interfaces\ImageInterface; +use Intervention\Image\Interfaces\ModifierInterface; -class GreyscaleModifier extends DriverSpecializedModifier +class GreyscaleModifier extends DriverSpecialized implements ModifierInterface { public function apply(ImageInterface $image): ImageInterface { diff --git a/src/Drivers/Imagick/Modifiers/InvertModifier.php b/src/Drivers/Imagick/Modifiers/InvertModifier.php index 0131df91..26b476b8 100644 --- a/src/Drivers/Imagick/Modifiers/InvertModifier.php +++ b/src/Drivers/Imagick/Modifiers/InvertModifier.php @@ -2,10 +2,11 @@ namespace Intervention\Image\Drivers\Imagick\Modifiers; -use Intervention\Image\Drivers\DriverSpecializedModifier; +use Intervention\Image\Drivers\DriverSpecialized; use Intervention\Image\Interfaces\ImageInterface; +use Intervention\Image\Interfaces\ModifierInterface; -class InvertModifier extends DriverSpecializedModifier +class InvertModifier extends DriverSpecialized implements ModifierInterface { public function apply(ImageInterface $image): ImageInterface { diff --git a/src/Drivers/Imagick/Modifiers/PixelateModifier.php b/src/Drivers/Imagick/Modifiers/PixelateModifier.php index 4f609252..a5a8ee20 100644 --- a/src/Drivers/Imagick/Modifiers/PixelateModifier.php +++ b/src/Drivers/Imagick/Modifiers/PixelateModifier.php @@ -2,14 +2,15 @@ namespace Intervention\Image\Drivers\Imagick\Modifiers; -use Intervention\Image\Drivers\DriverSpecializedModifier; +use Intervention\Image\Drivers\DriverSpecialized; use Intervention\Image\Drivers\Imagick\Frame; use Intervention\Image\Interfaces\ImageInterface; +use Intervention\Image\Interfaces\ModifierInterface; /** * @property int $size */ -class PixelateModifier extends DriverSpecializedModifier +class PixelateModifier extends DriverSpecialized implements ModifierInterface { public function apply(ImageInterface $image): ImageInterface { diff --git a/src/Drivers/Imagick/Modifiers/PlaceModifier.php b/src/Drivers/Imagick/Modifiers/PlaceModifier.php index 8b0d7ad5..6f2f164e 100644 --- a/src/Drivers/Imagick/Modifiers/PlaceModifier.php +++ b/src/Drivers/Imagick/Modifiers/PlaceModifier.php @@ -3,8 +3,9 @@ namespace Intervention\Image\Drivers\Imagick\Modifiers; use Imagick; -use Intervention\Image\Drivers\DriverSpecializedModifier; +use Intervention\Image\Drivers\DriverSpecialized; use Intervention\Image\Interfaces\ImageInterface; +use Intervention\Image\Interfaces\ModifierInterface; /** * @method mixed getPosition(ImageInterface $image, ImageInterface $watermark) @@ -13,7 +14,7 @@ * @property int $offset_x * @property int $offset_y */ -class PlaceModifier extends DriverSpecializedModifier +class PlaceModifier extends DriverSpecialized implements ModifierInterface { public function apply(ImageInterface $image): ImageInterface { diff --git a/src/Drivers/Imagick/Modifiers/ProfileModifier.php b/src/Drivers/Imagick/Modifiers/ProfileModifier.php index c8be88b2..33ff0524 100644 --- a/src/Drivers/Imagick/Modifiers/ProfileModifier.php +++ b/src/Drivers/Imagick/Modifiers/ProfileModifier.php @@ -2,15 +2,16 @@ namespace Intervention\Image\Drivers\Imagick\Modifiers; -use Intervention\Image\Drivers\DriverSpecializedModifier; +use Intervention\Image\Drivers\DriverSpecialized; use Intervention\Image\Exceptions\ColorException; use Intervention\Image\Interfaces\ImageInterface; +use Intervention\Image\Interfaces\ModifierInterface; use Intervention\Image\Interfaces\ProfileInterface; /** * @property ProfileInterface $profile */ -class ProfileModifier extends DriverSpecializedModifier +class ProfileModifier extends DriverSpecialized implements ModifierInterface { public function apply(ImageInterface $image): ImageInterface { diff --git a/src/Drivers/Imagick/Modifiers/ProfileRemovalModifier.php b/src/Drivers/Imagick/Modifiers/ProfileRemovalModifier.php index 6a4a79af..9e905f33 100644 --- a/src/Drivers/Imagick/Modifiers/ProfileRemovalModifier.php +++ b/src/Drivers/Imagick/Modifiers/ProfileRemovalModifier.php @@ -2,11 +2,12 @@ namespace Intervention\Image\Drivers\Imagick\Modifiers; -use Intervention\Image\Drivers\DriverSpecializedModifier; +use Intervention\Image\Drivers\DriverSpecialized; use Intervention\Image\Exceptions\ColorException; use Intervention\Image\Interfaces\ImageInterface; +use Intervention\Image\Interfaces\ModifierInterface; -class ProfileRemovalModifier extends DriverSpecializedModifier +class ProfileRemovalModifier extends DriverSpecialized implements ModifierInterface { public function apply(ImageInterface $image): ImageInterface { diff --git a/src/Drivers/Imagick/Modifiers/QuantizeColorsModifier.php b/src/Drivers/Imagick/Modifiers/QuantizeColorsModifier.php index 13e7963c..3d68023c 100644 --- a/src/Drivers/Imagick/Modifiers/QuantizeColorsModifier.php +++ b/src/Drivers/Imagick/Modifiers/QuantizeColorsModifier.php @@ -2,15 +2,16 @@ namespace Intervention\Image\Drivers\Imagick\Modifiers; -use Intervention\Image\Drivers\DriverSpecializedModifier; +use Intervention\Image\Drivers\DriverSpecialized; use Intervention\Image\Exceptions\InputException; use Intervention\Image\Interfaces\ImageInterface; +use Intervention\Image\Interfaces\ModifierInterface; /** * @property int $limit * @property mixed $background */ -class QuantizeColorsModifier extends DriverSpecializedModifier +class QuantizeColorsModifier extends DriverSpecialized implements ModifierInterface { public function apply(ImageInterface $image): ImageInterface { diff --git a/src/Drivers/Imagick/Modifiers/RemoveAnimationModifier.php b/src/Drivers/Imagick/Modifiers/RemoveAnimationModifier.php index 15147b17..b4f3e71e 100644 --- a/src/Drivers/Imagick/Modifiers/RemoveAnimationModifier.php +++ b/src/Drivers/Imagick/Modifiers/RemoveAnimationModifier.php @@ -3,14 +3,15 @@ namespace Intervention\Image\Drivers\Imagick\Modifiers; use Imagick; -use Intervention\Image\Drivers\DriverSpecializedModifier; +use Intervention\Image\Drivers\DriverSpecialized; use Intervention\Image\Interfaces\ImageInterface; +use Intervention\Image\Interfaces\ModifierInterface; /** * @method mixed chosenFrame(ImageInterface $image, int|string $position) * @property int|string $position */ -class RemoveAnimationModifier extends DriverSpecializedModifier +class RemoveAnimationModifier extends DriverSpecialized implements ModifierInterface { public function apply(ImageInterface $image): ImageInterface { diff --git a/src/Drivers/Imagick/Modifiers/ResizeCanvasModifier.php b/src/Drivers/Imagick/Modifiers/ResizeCanvasModifier.php index 11e29d6b..518c8856 100644 --- a/src/Drivers/Imagick/Modifiers/ResizeCanvasModifier.php +++ b/src/Drivers/Imagick/Modifiers/ResizeCanvasModifier.php @@ -3,15 +3,16 @@ namespace Intervention\Image\Drivers\Imagick\Modifiers; use ImagickDraw; -use Intervention\Image\Drivers\DriverSpecializedModifier; +use Intervention\Image\Drivers\DriverSpecialized; use Intervention\Image\Interfaces\ImageInterface; +use Intervention\Image\Interfaces\ModifierInterface; use Intervention\Image\Interfaces\SizeInterface; /** * @method SizeInterface cropSize(ImageInterface $image) * @property mixed $background */ -class ResizeCanvasModifier extends DriverSpecializedModifier +class ResizeCanvasModifier extends DriverSpecialized implements ModifierInterface { public function apply(ImageInterface $image): ImageInterface { diff --git a/src/Drivers/Imagick/Modifiers/ResizeModifier.php b/src/Drivers/Imagick/Modifiers/ResizeModifier.php index d016643a..9d0895a4 100644 --- a/src/Drivers/Imagick/Modifiers/ResizeModifier.php +++ b/src/Drivers/Imagick/Modifiers/ResizeModifier.php @@ -2,15 +2,16 @@ namespace Intervention\Image\Drivers\Imagick\Modifiers; -use Intervention\Image\Drivers\DriverSpecializedModifier; +use Intervention\Image\Drivers\DriverSpecialized; use Intervention\Image\Interfaces\ImageInterface; +use Intervention\Image\Interfaces\ModifierInterface; use Intervention\Image\Interfaces\SizeInterface; /** * @property null|int $width * @property null|int $height */ -class ResizeModifier extends DriverSpecializedModifier +class ResizeModifier extends DriverSpecialized implements ModifierInterface { public function apply(ImageInterface $image): ImageInterface { diff --git a/src/Drivers/Imagick/Modifiers/ResolutionModifier.php b/src/Drivers/Imagick/Modifiers/ResolutionModifier.php index fd44dec8..7b1d53cc 100644 --- a/src/Drivers/Imagick/Modifiers/ResolutionModifier.php +++ b/src/Drivers/Imagick/Modifiers/ResolutionModifier.php @@ -2,14 +2,15 @@ namespace Intervention\Image\Drivers\Imagick\Modifiers; -use Intervention\Image\Drivers\DriverSpecializedModifier; +use Intervention\Image\Drivers\DriverSpecialized; use Intervention\Image\Interfaces\ImageInterface; +use Intervention\Image\Interfaces\ModifierInterface; /** * @property int $x * @property int $y */ -class ResolutionModifier extends DriverSpecializedModifier +class ResolutionModifier extends DriverSpecialized implements ModifierInterface { public function apply(ImageInterface $image): ImageInterface { diff --git a/src/Drivers/Imagick/Modifiers/RotateModifier.php b/src/Drivers/Imagick/Modifiers/RotateModifier.php index b7f15a12..22b65e49 100644 --- a/src/Drivers/Imagick/Modifiers/RotateModifier.php +++ b/src/Drivers/Imagick/Modifiers/RotateModifier.php @@ -2,14 +2,15 @@ namespace Intervention\Image\Drivers\Imagick\Modifiers; -use Intervention\Image\Drivers\DriverSpecializedModifier; +use Intervention\Image\Drivers\DriverSpecialized; use Intervention\Image\Interfaces\ImageInterface; +use Intervention\Image\Interfaces\ModifierInterface; /** * @method mixed rotationAngle() * @property mixed $background */ -class RotateModifier extends DriverSpecializedModifier +class RotateModifier extends DriverSpecialized implements ModifierInterface { public function apply(ImageInterface $image): ImageInterface { diff --git a/src/Drivers/Imagick/Modifiers/SharpenModifier.php b/src/Drivers/Imagick/Modifiers/SharpenModifier.php index 25ed5a90..cc71e5f6 100644 --- a/src/Drivers/Imagick/Modifiers/SharpenModifier.php +++ b/src/Drivers/Imagick/Modifiers/SharpenModifier.php @@ -2,13 +2,14 @@ namespace Intervention\Image\Drivers\Imagick\Modifiers; -use Intervention\Image\Drivers\DriverSpecializedModifier; +use Intervention\Image\Drivers\DriverSpecialized; use Intervention\Image\Interfaces\ImageInterface; +use Intervention\Image\Interfaces\ModifierInterface; /** * @property int $amount */ -class SharpenModifier extends DriverSpecializedModifier +class SharpenModifier extends DriverSpecialized implements ModifierInterface { public function apply(ImageInterface $image): ImageInterface { diff --git a/src/Interfaces/DriverInterface.php b/src/Interfaces/DriverInterface.php index 675ced87..ec936237 100644 --- a/src/Interfaces/DriverInterface.php +++ b/src/Interfaces/DriverInterface.php @@ -15,9 +15,9 @@ public function id(): string; * Resolve given object into a specialized version for the current driver * * @param object $input - * @return object + * @return ModifierInterface|AnalyzerInterface|EncoderInterface|DecoderInterface */ - public function specialize(object $input): object; + public function specialize(object $input): ModifierInterface|AnalyzerInterface|EncoderInterface|DecoderInterface; /** * Create new image instance with the current driver in given dimensions diff --git a/tests/Drivers/DriverSpecializedAnalyzerTest.php b/tests/Drivers/DriverSpecializedAnalyzerTest.php deleted file mode 100644 index b36473b4..00000000 --- a/tests/Drivers/DriverSpecializedAnalyzerTest.php +++ /dev/null @@ -1,29 +0,0 @@ -makePartial(); - - $this->assertInstanceOf(DriverInterface::class, $analyzer->driver()); - } -} From c5ad95c2c3f22214b68817951e4c24e5bda72266 Mon Sep 17 00:00:00 2001 From: Oliver Vogel Date: Sun, 31 Dec 2023 18:19:30 +0100 Subject: [PATCH 03/11] Add specializable decoders --- src/Decoders/AbstractDecoder.php | 16 ++++++++++++++++ src/Decoders/FilePathImageDecoder.php | 7 +++++++ src/Drivers/AbstractDecoder.php | 2 +- src/Drivers/AbstractDriver.php | 5 +++++ src/Drivers/Gd/Driver.php | 4 ++-- src/ImageManager.php | 1 + src/Interfaces/DriverInterface.php | 3 ++- 7 files changed, 34 insertions(+), 4 deletions(-) create mode 100644 src/Decoders/AbstractDecoder.php create mode 100644 src/Decoders/FilePathImageDecoder.php diff --git a/src/Decoders/AbstractDecoder.php b/src/Decoders/AbstractDecoder.php new file mode 100644 index 00000000..09c707aa --- /dev/null +++ b/src/Decoders/AbstractDecoder.php @@ -0,0 +1,16 @@ +handle($input); + return (new InputHandler($decoders))->handle($input); } /** diff --git a/src/ImageManager.php b/src/ImageManager.php index ad93e39a..1dc61ca7 100644 --- a/src/ImageManager.php +++ b/src/ImageManager.php @@ -6,6 +6,7 @@ use Intervention\Image\Interfaces\ImageInterface; use Intervention\Image\Drivers\Gd\Driver as GdDriver; use Intervention\Image\Drivers\Imagick\Driver as ImagickDriver; +use Intervention\Image\Interfaces\DecoderInterface; final class ImageManager { diff --git a/src/Interfaces/DriverInterface.php b/src/Interfaces/DriverInterface.php index ec936237..057aa429 100644 --- a/src/Interfaces/DriverInterface.php +++ b/src/Interfaces/DriverInterface.php @@ -40,9 +40,10 @@ public function createAnimation(callable $init): ImageInterface; * Handle given input by decoding it to ImageInterface or ColorInterface * * @param mixed $input + * @param array $decoders * @return ImageInterface|ColorInterface */ - public function handleInput(mixed $input): ImageInterface|ColorInterface; + public function handleInput(mixed $input, array $decoders = []): ImageInterface|ColorInterface; /** * Return color processor for the given colorspace From 0fe3834385ae4e5925e0b9ca865899d5e2ab94f7 Mon Sep 17 00:00:00 2001 From: Oliver Vogel Date: Fri, 5 Jan 2024 11:59:59 +0100 Subject: [PATCH 04/11] Add SpecializableInterface and tests --- src/Analyzers/AbstractAnalyzer.php | 3 +- src/Decoders/AbstractDecoder.php | 3 +- src/Drivers/AbstractDriver.php | 34 +---------------- src/Drivers/DriverSpecialized.php | 6 ++- src/Drivers/Imagick/Driver.php | 4 +- src/Encoders/AbstractEncoder.php | 7 ++-- src/Image.php | 2 +- src/Interfaces/ImageInterface.php | 4 +- src/Interfaces/SpecializableInterface.php | 7 ++++ src/Interfaces/SpecializedInterface.php | 2 + src/Modifiers/AbstractModifier.php | 3 +- .../Drivers/DriverSpecializedEncoderTest.php | 12 ------ tests/Drivers/DriverSpecializedTest.php | 38 +++++++++++++++++++ 13 files changed, 69 insertions(+), 56 deletions(-) create mode 100644 src/Interfaces/SpecializableInterface.php create mode 100644 tests/Drivers/DriverSpecializedTest.php diff --git a/src/Analyzers/AbstractAnalyzer.php b/src/Analyzers/AbstractAnalyzer.php index 74509e9b..2768547d 100644 --- a/src/Analyzers/AbstractAnalyzer.php +++ b/src/Analyzers/AbstractAnalyzer.php @@ -4,8 +4,9 @@ use Intervention\Image\Interfaces\AnalyzerInterface; use Intervention\Image\Interfaces\ImageInterface; +use Intervention\Image\Interfaces\SpecializableInterface; -abstract class AbstractAnalyzer implements AnalyzerInterface +abstract class AbstractAnalyzer implements AnalyzerInterface, SpecializableInterface { /** * {@inheritdoc} diff --git a/src/Decoders/AbstractDecoder.php b/src/Decoders/AbstractDecoder.php index 09c707aa..3b586d65 100644 --- a/src/Decoders/AbstractDecoder.php +++ b/src/Decoders/AbstractDecoder.php @@ -6,8 +6,9 @@ use Intervention\Image\Interfaces\ColorInterface; use Intervention\Image\Interfaces\DecoderInterface; use Intervention\Image\Interfaces\ImageInterface; +use Intervention\Image\Interfaces\SpecializableInterface; -abstract class AbstractDecoder implements DecoderInterface +abstract class AbstractDecoder implements DecoderInterface, SpecializableInterface { public function decode(mixed $input): ImageInterface|ColorInterface { diff --git a/src/Drivers/AbstractDriver.php b/src/Drivers/AbstractDriver.php index 89c2ab97..f86d8fff 100644 --- a/src/Drivers/AbstractDriver.php +++ b/src/Drivers/AbstractDriver.php @@ -2,16 +2,13 @@ namespace Intervention\Image\Drivers; -use Intervention\Image\Analyzers\AbstractAnalyzer; -use Intervention\Image\Decoders\AbstractDecoder; -use Intervention\Image\Encoders\AbstractEncoder; use Intervention\Image\Exceptions\NotSupportedException; use Intervention\Image\Interfaces\AnalyzerInterface; use Intervention\Image\Interfaces\DecoderInterface; use Intervention\Image\Interfaces\DriverInterface; use Intervention\Image\Interfaces\EncoderInterface; use Intervention\Image\Interfaces\ModifierInterface; -use Intervention\Image\Modifiers\AbstractModifier; +use Intervention\Image\Interfaces\SpecializableInterface; use ReflectionClass; abstract class AbstractDriver implements DriverInterface @@ -30,7 +27,7 @@ public function __construct() */ public function specialize(object $input): ModifierInterface|AnalyzerInterface|EncoderInterface|DecoderInterface { - if ($this->isExternal($input)) { + if (!($input instanceof SpecializableInterface)) { return $input; } @@ -49,31 +46,4 @@ public function specialize(object $input): ModifierInterface|AnalyzerInterface|E 'buildSpecialized' ], $input, $this); } - - /** - * Determine if given object is external custom modifier, analyzer or encoder - * - * @param object $input - * @return bool - */ - private function isExternal(object $input): bool - { - if ($input instanceof AbstractModifier) { - return false; - } - - if ($input instanceof AbstractAnalyzer) { - return false; - } - - if ($input instanceof AbstractEncoder) { - return false; - } - - if ($input instanceof AbstractDecoder) { - return false; - } - - return true; - } } diff --git a/src/Drivers/DriverSpecialized.php b/src/Drivers/DriverSpecialized.php index 5adb9ad4..4cd173aa 100644 --- a/src/Drivers/DriverSpecialized.php +++ b/src/Drivers/DriverSpecialized.php @@ -5,11 +5,15 @@ use Intervention\Image\Interfaces\DriverInterface; use Intervention\Image\Interfaces\SpecializedInterface; -class DriverSpecialized implements SpecializedInterface +abstract class DriverSpecialized implements SpecializedInterface { protected DriverInterface $driver; protected object $generic; + public function __construct() + { + } + public static function buildSpecialized(object $generic, DriverInterface $driver): SpecializedInterface { $specialized = new static(); diff --git a/src/Drivers/Imagick/Driver.php b/src/Drivers/Imagick/Driver.php index 99ea0449..aecb11ec 100644 --- a/src/Drivers/Imagick/Driver.php +++ b/src/Drivers/Imagick/Driver.php @@ -105,9 +105,9 @@ public function __invoke(): ImageInterface * * @see DriverInterface::handleInput() */ - public function handleInput(mixed $input): ImageInterface|ColorInterface + public function handleInput(mixed $input, array $decoders = []): ImageInterface|ColorInterface { - return (new InputHandler())->handle($input); + return (new InputHandler($decoders))->handle($input); } /** diff --git a/src/Encoders/AbstractEncoder.php b/src/Encoders/AbstractEncoder.php index 418e07ac..6bf0d047 100644 --- a/src/Encoders/AbstractEncoder.php +++ b/src/Encoders/AbstractEncoder.php @@ -2,18 +2,19 @@ namespace Intervention\Image\Encoders; -use Intervention\Image\EncodedImage; +use Intervention\Image\Interfaces\EncodedImageInterface; use Intervention\Image\Interfaces\EncoderInterface; use Intervention\Image\Interfaces\ImageInterface; +use Intervention\Image\Interfaces\SpecializableInterface; -abstract class AbstractEncoder implements EncoderInterface +abstract class AbstractEncoder implements EncoderInterface, SpecializableInterface { /** * {@inheritdoc} * * @see EncoderInterface::encode() */ - public function encode(ImageInterface $image): EncodedImage + public function encode(ImageInterface $image): EncodedImageInterface { return $image->encode($this); } diff --git a/src/Image.php b/src/Image.php index b571ca44..27552c65 100644 --- a/src/Image.php +++ b/src/Image.php @@ -247,7 +247,7 @@ public function analyze(AnalyzerInterface $analyzer): mixed * * @see ImageInterface::encode() */ - public function encode(EncoderInterface $encoder = new AutoEncoder()): EncodedImage + public function encode(EncoderInterface $encoder = new AutoEncoder()): EncodedImageInterface { return $this->driver->specialize($encoder)->encode($this); } diff --git a/src/Interfaces/ImageInterface.php b/src/Interfaces/ImageInterface.php index c50144d1..6b033a1e 100644 --- a/src/Interfaces/ImageInterface.php +++ b/src/Interfaces/ImageInterface.php @@ -63,9 +63,9 @@ public function size(): SizeInterface; * Encode image with given encoder * * @param EncoderInterface $encoder - * @return EncodedImage + * @return EncodedImageInterface */ - public function encode(EncoderInterface $encoder): EncodedImage; + public function encode(EncoderInterface $encoder): EncodedImageInterface; /** * Save the image to the specified path in the file system. If no path is diff --git a/src/Interfaces/SpecializableInterface.php b/src/Interfaces/SpecializableInterface.php new file mode 100644 index 00000000..24ba6a4b --- /dev/null +++ b/src/Interfaces/SpecializableInterface.php @@ -0,0 +1,7 @@ +assertEquals('result', $result); } - - public function testGetAttributes(): void - { - $encoder = Mockery::mock(DriverSpecializedEncoder::class, [ - new JpegEncoder(quality: 10), - Mockery::mock(DriverInterface::class), - ])->makePartial(); - - $this->assertEquals(10, $encoder->quality); - } } diff --git a/tests/Drivers/DriverSpecializedTest.php b/tests/Drivers/DriverSpecializedTest.php new file mode 100644 index 00000000..0d32aeb0 --- /dev/null +++ b/tests/Drivers/DriverSpecializedTest.php @@ -0,0 +1,38 @@ +assertInstanceOf(JpegEncoder::class, $specialized->generic()); + $this->assertInstanceOf(DriverInterface::class, $specialized->driver()); + $this->assertEquals(10, $specialized->quality); + } +} From b9c636865608562edc1e685324a1765579436734 Mon Sep 17 00:00:00 2001 From: Oliver Vogel Date: Fri, 5 Jan 2024 12:34:34 +0100 Subject: [PATCH 05/11] Add generic decoders --- src/Decoders/Base64ImageDecoder.php | 7 ++++++ src/Decoders/BinaryImageDecoder.php | 7 ++++++ src/Decoders/DataUriImageDecoder.php | 7 ++++++ src/Decoders/FilePointerImageDecoder.php | 7 ++++++ src/Decoders/ImageObjectDecoder.php | 7 ++++++ src/Decoders/SplFileInfoImageDecoder.php | 7 ++++++ src/Drivers/AbstractDriver.php | 28 ++++++++++++++++-------- src/Drivers/Gd/Driver.php | 2 +- src/Drivers/Imagick/Driver.php | 2 +- src/ImageManager.php | 22 ++++++++++++++++--- src/Interfaces/DriverInterface.php | 12 ++++++++-- 11 files changed, 92 insertions(+), 16 deletions(-) create mode 100644 src/Decoders/Base64ImageDecoder.php create mode 100644 src/Decoders/BinaryImageDecoder.php create mode 100644 src/Decoders/DataUriImageDecoder.php create mode 100644 src/Decoders/FilePointerImageDecoder.php create mode 100644 src/Decoders/ImageObjectDecoder.php create mode 100644 src/Decoders/SplFileInfoImageDecoder.php diff --git a/src/Decoders/Base64ImageDecoder.php b/src/Decoders/Base64ImageDecoder.php new file mode 100644 index 00000000..f15a90d7 --- /dev/null +++ b/src/Decoders/Base64ImageDecoder.php @@ -0,0 +1,7 @@ +getNamespaceName(); - $class_path = substr(get_class($input), strlen("Intervention\\Image\\")); + $class_path = substr(get_class($object), strlen("Intervention\\Image\\")); $classname = $driver_namespace . "\\" . $class_path; if (!class_exists($classname)) { @@ -44,6 +42,18 @@ public function specialize(object $input): ModifierInterface|AnalyzerInterface|E return forward_static_call([ $classname, 'buildSpecialized' - ], $input, $this); + ], $object, $this); + } + + /** + * {@inheritdoc} + * + * @see DriverInterface::specializeMultiple() + */ + public function specializeMultiple(array $objects): array + { + return array_map(function ($classname) { + return $this->specialize(new $classname()); + }, $objects); } } diff --git a/src/Drivers/Gd/Driver.php b/src/Drivers/Gd/Driver.php index d1598eb7..2db18f48 100644 --- a/src/Drivers/Gd/Driver.php +++ b/src/Drivers/Gd/Driver.php @@ -105,7 +105,7 @@ public function __invoke(): ImageInterface */ public function handleInput(mixed $input, array $decoders = []): ImageInterface|ColorInterface { - return (new InputHandler($decoders))->handle($input); + return (new InputHandler($this->specializeMultiple($decoders)))->handle($input); } /** diff --git a/src/Drivers/Imagick/Driver.php b/src/Drivers/Imagick/Driver.php index aecb11ec..aaf86e81 100644 --- a/src/Drivers/Imagick/Driver.php +++ b/src/Drivers/Imagick/Driver.php @@ -107,7 +107,7 @@ public function __invoke(): ImageInterface */ public function handleInput(mixed $input, array $decoders = []): ImageInterface|ColorInterface { - return (new InputHandler($decoders))->handle($input); + return (new InputHandler($this->specializeMultiple($decoders)))->handle($input); } /** diff --git a/src/ImageManager.php b/src/ImageManager.php index 1dc61ca7..78ae8fed 100644 --- a/src/ImageManager.php +++ b/src/ImageManager.php @@ -61,7 +61,7 @@ public function create(int $width, int $height): ImageInterface } /** - * Create new image instance from given source which can be one of the following + * Create new image instance from given input which can be one of the following * * - Path in filesystem * - File Pointer resource @@ -71,12 +71,28 @@ public function create(int $width, int $height): ImageInterface * - Data Uri * - Intervention\Image\Image Instance * + * To decode the raw input data, you can optionally specify a decoding strategy + * with the second parameter. This can be an array of class names or objects + * of decoders to be processed in sequence. In this case, the input must be + * decodedable with one of the decoders passed. It is also possible to pass + * a single object or class name of a decoder. + * + * If the second parameter is not set, an attempt to decode the input is made + * with all available decoders of the driver. + * * @param mixed $input + * @param string|array|DecoderInterface $decoders * @return ImageInterface */ - public function read(mixed $input): ImageInterface + public function read(mixed $input, string|array|DecoderInterface $decoders = []): ImageInterface { - return $this->driver->handleInput($input); + return $this->driver->handleInput( + $input, + match (true) { + is_string($decoders), is_a($decoders, DecoderInterface::class) => [$decoders], + default => $decoders, + } + ); } /** diff --git a/src/Interfaces/DriverInterface.php b/src/Interfaces/DriverInterface.php index 057aa429..828d5eae 100644 --- a/src/Interfaces/DriverInterface.php +++ b/src/Interfaces/DriverInterface.php @@ -14,10 +14,18 @@ public function id(): string; /** * Resolve given object into a specialized version for the current driver * - * @param object $input + * @param object $object * @return ModifierInterface|AnalyzerInterface|EncoderInterface|DecoderInterface */ - public function specialize(object $input): ModifierInterface|AnalyzerInterface|EncoderInterface|DecoderInterface; + public function specialize(object $object): ModifierInterface|AnalyzerInterface|EncoderInterface|DecoderInterface; + + /** + * Resolve each object in given array into a specialized version for the current driver + * + * @param array $objects + * @return array + */ + public function specializeMultiple(array $objects): array; /** * Create new image instance with the current driver in given dimensions From 9f15cf448c3eb50a7a26547609cc7afdc547b58c Mon Sep 17 00:00:00 2001 From: Oliver Vogel Date: Fri, 5 Jan 2024 12:44:04 +0100 Subject: [PATCH 06/11] Add info to doc block --- src/ImageManager.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/ImageManager.php b/src/ImageManager.php index 78ae8fed..d600620a 100644 --- a/src/ImageManager.php +++ b/src/ImageManager.php @@ -77,6 +77,9 @@ public function create(int $width, int $height): ImageInterface * decodedable with one of the decoders passed. It is also possible to pass * a single object or class name of a decoder. * + * All decoders that implement the `DecoderInterface::class` can be passed. Usually + * a selection of classes of the namespace `Intervention\Image\Decoders` + * * If the second parameter is not set, an attempt to decode the input is made * with all available decoders of the driver. * From 7e8966e188515cfa6449fe30002f32c6eaa157d9 Mon Sep 17 00:00:00 2001 From: Oliver Vogel Date: Fri, 5 Jan 2024 12:48:48 +0100 Subject: [PATCH 07/11] Add ImageManager::read() tests --- tests/ImageManagerTest.php | 65 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) diff --git a/tests/ImageManagerTest.php b/tests/ImageManagerTest.php index 5094a504..4fc8a220 100644 --- a/tests/ImageManagerTest.php +++ b/tests/ImageManagerTest.php @@ -2,6 +2,7 @@ namespace Intervention\Image\Tests; +use Intervention\Image\Decoders\FilePathImageDecoder; use Intervention\Image\Drivers\Gd\Driver as GdDriver; use Intervention\Image\Drivers\Imagick\Driver as ImagickDriver; use Intervention\Image\ImageManager; @@ -55,6 +56,38 @@ public function testReadGd() $this->assertInstanceOf(ImageInterface::class, $image); } + /** @requires extension gd */ + public function testReadGdWithDecoderClassname(): void + { + $manager = new ImageManager(GdDriver::class); + $image = $manager->read(__DIR__ . '/images/red.gif', FilePathImageDecoder::class); + $this->assertInstanceOf(ImageInterface::class, $image); + } + + /** @requires extension gd */ + public function testReadGdWithDecoderInstance(): void + { + $manager = new ImageManager(GdDriver::class); + $image = $manager->read(__DIR__ . '/images/red.gif', new FilePathImageDecoder()); + $this->assertInstanceOf(ImageInterface::class, $image); + } + + /** @requires extension gd */ + public function testReadGdWithDecoderClassnameArray(): void + { + $manager = new ImageManager(GdDriver::class); + $image = $manager->read(__DIR__ . '/images/red.gif', [FilePathImageDecoder::class]); + $this->assertInstanceOf(ImageInterface::class, $image); + } + + /** @requires extension gd */ + public function testReadGdWithDecoderInstanceArray(): void + { + $manager = new ImageManager(GdDriver::class); + $image = $manager->read(__DIR__ . '/images/red.gif', [new FilePathImageDecoder()]); + $this->assertInstanceOf(ImageInterface::class, $image); + } + /** @requires extension imagick */ public function testCreateImagick() { @@ -70,4 +103,36 @@ public function testReadImagick() $image = $manager->read(__DIR__ . '/images/red.gif'); $this->assertInstanceOf(ImageInterface::class, $image); } + + /** @requires extension imagick */ + public function testReadImagickWithDecoderClassname(): void + { + $manager = new ImageManager(ImagickDriver::class); + $image = $manager->read(__DIR__ . '/images/red.gif', FilePathImageDecoder::class); + $this->assertInstanceOf(ImageInterface::class, $image); + } + + /** @requires extension imagick */ + public function testReadImagickWithDecoderInstance(): void + { + $manager = new ImageManager(ImagickDriver::class); + $image = $manager->read(__DIR__ . '/images/red.gif', new FilePathImageDecoder()); + $this->assertInstanceOf(ImageInterface::class, $image); + } + + /** @requires extension imagick */ + public function testReadImagickWithDecoderClassnameArray(): void + { + $manager = new ImageManager(ImagickDriver::class); + $image = $manager->read(__DIR__ . '/images/red.gif', [FilePathImageDecoder::class]); + $this->assertInstanceOf(ImageInterface::class, $image); + } + + /** @requires extension imagick */ + public function testReadImagickWithDecoderInstanceArray(): void + { + $manager = new ImageManager(ImagickDriver::class); + $image = $manager->read(__DIR__ . '/images/red.gif', [new FilePathImageDecoder()]); + $this->assertInstanceOf(ImageInterface::class, $image); + } } From 30ed4a649cac4845921e160024e0a54acc2e6eca Mon Sep 17 00:00:00 2001 From: Oliver Vogel Date: Wed, 10 Jan 2024 11:22:05 +0100 Subject: [PATCH 08/11] Add dynamic Encoder options --- src/Encoders/AbstractEncoder.php | 30 ++++++++++- src/Encoders/AutoEncoder.php | 10 ---- src/Encoders/AvifEncoder.php | 7 ++- src/Encoders/BmpEncoder.php | 4 +- src/Encoders/FileExtensionEncoder.php | 5 +- src/Encoders/FilePathEncoder.php | 8 ++- src/Encoders/GifEncoder.php | 4 +- src/Encoders/Jpeg2000Encoder.php | 7 ++- src/Encoders/JpegEncoder.php | 7 ++- src/Encoders/MediaTypeEncoder.php | 22 +++----- src/Encoders/PngEncoder.php | 4 +- src/Encoders/TiffEncoder.php | 7 ++- src/Encoders/WebpEncoder.php | 7 ++- src/Image.php | 72 +++++++++++++-------------- src/Interfaces/ImageInterface.php | 38 +++++++------- 15 files changed, 126 insertions(+), 106 deletions(-) diff --git a/src/Encoders/AbstractEncoder.php b/src/Encoders/AbstractEncoder.php index 6bf0d047..72165f97 100644 --- a/src/Encoders/AbstractEncoder.php +++ b/src/Encoders/AbstractEncoder.php @@ -5,10 +5,36 @@ use Intervention\Image\Interfaces\EncodedImageInterface; use Intervention\Image\Interfaces\EncoderInterface; use Intervention\Image\Interfaces\ImageInterface; -use Intervention\Image\Interfaces\SpecializableInterface; -abstract class AbstractEncoder implements EncoderInterface, SpecializableInterface +abstract class AbstractEncoder implements EncoderInterface { + public const DEFAULT_QUALITY = 75; + public const DEFAULT_COMPRESSION = 0; + public const DEFAULT_BIT_DEPTH = 8; + + public int $quality = self::DEFAULT_QUALITY; + public int $compression = self::DEFAULT_COMPRESSION; + public int $bitDepth = self::DEFAULT_BIT_DEPTH; + + /** + * Create new encoder instance + * + * @param mixed $options + * @return void + */ + public function __construct(mixed ...$options) + { + if (is_array($options) && array_is_list($options)) { + $this->quality = $options[0] ?? self::DEFAULT_QUALITY; + $this->compression = $options[1] ?? self::DEFAULT_COMPRESSION; + $this->bitDepth = $options[2] ?? self::DEFAULT_BIT_DEPTH; + } else { + $this->quality = $options['quality'] ?? self::DEFAULT_QUALITY; + $this->compression = $options['compression'] ?? self::DEFAULT_COMPRESSION; + $this->bitDepth = $options['bitDepth'] ?? self::DEFAULT_BIT_DEPTH; + } + } + /** * {@inheritdoc} * diff --git a/src/Encoders/AutoEncoder.php b/src/Encoders/AutoEncoder.php index 8ef68563..614b2e6a 100644 --- a/src/Encoders/AutoEncoder.php +++ b/src/Encoders/AutoEncoder.php @@ -7,16 +7,6 @@ class AutoEncoder extends MediaTypeEncoder { - /** - * Create new encoder instance - * - * @param int $quality - * @return void - */ - public function __construct(protected int $quality = 75) - { - } - /** * {@inheritdoc} * diff --git a/src/Encoders/AvifEncoder.php b/src/Encoders/AvifEncoder.php index dfa64854..e9e91c48 100644 --- a/src/Encoders/AvifEncoder.php +++ b/src/Encoders/AvifEncoder.php @@ -2,9 +2,8 @@ namespace Intervention\Image\Encoders; -class AvifEncoder extends AbstractEncoder +use Intervention\Image\Interfaces\SpecializableInterface; + +class AvifEncoder extends AbstractEncoder implements SpecializableInterface { - public function __construct(public int $quality = 75) - { - } } diff --git a/src/Encoders/BmpEncoder.php b/src/Encoders/BmpEncoder.php index 4cf0c6e6..787df9af 100644 --- a/src/Encoders/BmpEncoder.php +++ b/src/Encoders/BmpEncoder.php @@ -2,6 +2,8 @@ namespace Intervention\Image\Encoders; -class BmpEncoder extends AbstractEncoder +use Intervention\Image\Interfaces\SpecializableInterface; + +class BmpEncoder extends AbstractEncoder implements SpecializableInterface { } diff --git a/src/Encoders/FileExtensionEncoder.php b/src/Encoders/FileExtensionEncoder.php index 5637792e..58a67662 100644 --- a/src/Encoders/FileExtensionEncoder.php +++ b/src/Encoders/FileExtensionEncoder.php @@ -13,11 +13,12 @@ class FileExtensionEncoder extends AutoEncoder * Create new encoder instance to encode to format of given file extension * * @param null|string $extension - * @param int $quality + * @param mixed $options * @return void */ - public function __construct(protected ?string $extension = null, protected int $quality = 75) + public function __construct(protected ?string $extension = null, mixed ...$options) { + parent::__construct(null, ...$options); } /** diff --git a/src/Encoders/FilePathEncoder.php b/src/Encoders/FilePathEncoder.php index d93892aa..572a0dd4 100644 --- a/src/Encoders/FilePathEncoder.php +++ b/src/Encoders/FilePathEncoder.php @@ -11,11 +11,15 @@ class FilePathEncoder extends FileExtensionEncoder * Create new encoder instance to encode to format of file extension in given path * * @param null|string $path - * @param int $quality + * @param mixed $options * @return void */ - public function __construct(protected ?string $path = null, protected int $quality = 75) + public function __construct(protected ?string $path = null, mixed ...$options) { + parent::__construct( + is_null($path) ? $path : pathinfo($path, PATHINFO_EXTENSION), + ...$options + ); } /** diff --git a/src/Encoders/GifEncoder.php b/src/Encoders/GifEncoder.php index 5fd836b4..0f566f3e 100644 --- a/src/Encoders/GifEncoder.php +++ b/src/Encoders/GifEncoder.php @@ -2,6 +2,8 @@ namespace Intervention\Image\Encoders; -class GifEncoder extends AbstractEncoder +use Intervention\Image\Interfaces\SpecializableInterface; + +class GifEncoder extends AbstractEncoder implements SpecializableInterface { } diff --git a/src/Encoders/Jpeg2000Encoder.php b/src/Encoders/Jpeg2000Encoder.php index 0eb60a54..a83b61b8 100644 --- a/src/Encoders/Jpeg2000Encoder.php +++ b/src/Encoders/Jpeg2000Encoder.php @@ -2,9 +2,8 @@ namespace Intervention\Image\Encoders; -class Jpeg2000Encoder extends AbstractEncoder +use Intervention\Image\Interfaces\SpecializableInterface; + +class Jpeg2000Encoder extends AbstractEncoder implements SpecializableInterface { - public function __construct(public int $quality = 75) - { - } } diff --git a/src/Encoders/JpegEncoder.php b/src/Encoders/JpegEncoder.php index 3a63de5c..93a22659 100644 --- a/src/Encoders/JpegEncoder.php +++ b/src/Encoders/JpegEncoder.php @@ -2,9 +2,8 @@ namespace Intervention\Image\Encoders; -class JpegEncoder extends AbstractEncoder +use Intervention\Image\Interfaces\SpecializableInterface; + +class JpegEncoder extends AbstractEncoder implements SpecializableInterface { - public function __construct(public int $quality = 75) - { - } } diff --git a/src/Encoders/MediaTypeEncoder.php b/src/Encoders/MediaTypeEncoder.php index 1fb6751b..be9c6027 100644 --- a/src/Encoders/MediaTypeEncoder.php +++ b/src/Encoders/MediaTypeEncoder.php @@ -7,17 +7,11 @@ use Intervention\Image\Interfaces\EncoderInterface; use Intervention\Image\Interfaces\ImageInterface; -class MediaTypeEncoder implements EncoderInterface +class MediaTypeEncoder extends AbstractEncoder implements EncoderInterface { - /** - * Create new encoder instance to encode given media (mime) type - * - * @param null|string $type - * @param int $quality - * @return void - */ - public function __construct(protected ?string $type = null, protected int $quality = 75) + public function __construct(protected ?string $type = null, ...$options) { + parent::__construct(...$options); } /** @@ -44,14 +38,14 @@ public function encode(ImageInterface $image): EncodedImageInterface protected function encoderByMediaType(string $type): EncoderInterface { return match (strtolower($type)) { - 'image/webp' => new WebpEncoder($this->quality), - 'image/avif' => new AvifEncoder($this->quality), - 'image/jpeg' => new JpegEncoder($this->quality), + 'image/webp' => new WebpEncoder(quality: $this->quality), + 'image/avif' => new AvifEncoder(quality: $this->quality), + 'image/jpeg' => new JpegEncoder(quality: $this->quality), 'image/bmp' => new BmpEncoder(), 'image/gif' => new GifEncoder(), 'image/png' => new PngEncoder(), - 'image/tiff' => new TiffEncoder($this->quality), - 'image/jp2', 'image/jpx', 'image/jpm' => new Jpeg2000Encoder($this->quality), + 'image/tiff' => new TiffEncoder(quality: $this->quality), + 'image/jp2', 'image/jpx', 'image/jpm' => new Jpeg2000Encoder(quality: $this->quality), default => throw new EncoderException('No encoder found for media type (' . $type . ').'), }; } diff --git a/src/Encoders/PngEncoder.php b/src/Encoders/PngEncoder.php index 1b8660d1..507488f2 100644 --- a/src/Encoders/PngEncoder.php +++ b/src/Encoders/PngEncoder.php @@ -2,6 +2,8 @@ namespace Intervention\Image\Encoders; -class PngEncoder extends AbstractEncoder +use Intervention\Image\Interfaces\SpecializableInterface; + +class PngEncoder extends AbstractEncoder implements SpecializableInterface { } diff --git a/src/Encoders/TiffEncoder.php b/src/Encoders/TiffEncoder.php index 7bab4397..89862fd3 100644 --- a/src/Encoders/TiffEncoder.php +++ b/src/Encoders/TiffEncoder.php @@ -2,9 +2,8 @@ namespace Intervention\Image\Encoders; -class TiffEncoder extends AbstractEncoder +use Intervention\Image\Interfaces\SpecializableInterface; + +class TiffEncoder extends AbstractEncoder implements SpecializableInterface { - public function __construct(public int $quality = 75) - { - } } diff --git a/src/Encoders/WebpEncoder.php b/src/Encoders/WebpEncoder.php index 0c63e630..a24af3dd 100644 --- a/src/Encoders/WebpEncoder.php +++ b/src/Encoders/WebpEncoder.php @@ -2,9 +2,8 @@ namespace Intervention\Image\Encoders; -class WebpEncoder extends AbstractEncoder +use Intervention\Image\Interfaces\SpecializableInterface; + +class WebpEncoder extends AbstractEncoder implements SpecializableInterface { - public function __construct(public int $quality = 75) - { - } } diff --git a/src/Image.php b/src/Image.php index 9237c0cd..1be15e9d 100644 --- a/src/Image.php +++ b/src/Image.php @@ -257,7 +257,7 @@ public function encode(EncoderInterface $encoder = new AutoEncoder()): EncodedIm * * @see ImageInterface::save() */ - public function save(?string $path = null, int $quality = 75): ImageInterface + public function save(?string $path = null, ...$options): ImageInterface { $path = is_null($path) ? $this->origin()->filePath() : $path; @@ -267,10 +267,10 @@ public function save(?string $path = null, int $quality = 75): ImageInterface try { // try to determine encoding format by file extension of the path - $encoded = $this->encodeByPath($path, $quality); + $encoded = $this->encodeByPath($path, ...$options); } catch (EncoderException) { // fallback to encoding format by media type - $encoded = $this->encodeByMediaType(quality: $quality); + $encoded = $this->encodeByMediaType(null, ...$options); } $encoded->save($path); @@ -779,9 +779,9 @@ public function drawLine(callable $init): ImageInterface * * @see ImageInterface::encodeByMediaType() */ - public function encodeByMediaType(?string $type = null, int $quality = 75): EncodedImageInterface + public function encodeByMediaType(?string $type = null, ...$options): EncodedImageInterface { - return $this->encode(new MediaTypeEncoder($type, $quality)); + return $this->encode(new MediaTypeEncoder($type, ...$options)); } /** @@ -789,9 +789,9 @@ public function encodeByMediaType(?string $type = null, int $quality = 75): Enco * * @see ImageInterface::encodeByExtension() */ - public function encodeByExtension(?string $extension = null, int $quality = 75): EncodedImageInterface + public function encodeByExtension(?string $extension = null, mixed ...$options): EncodedImageInterface { - return $this->encode(new FileExtensionEncoder($extension, $quality)); + return $this->encode(new FileExtensionEncoder($extension, ...$options)); } /** @@ -799,9 +799,9 @@ public function encodeByExtension(?string $extension = null, int $quality = 75): * * @see ImageInterface::encodeByPath() */ - public function encodeByPath(?string $path = null, int $quality = 75): EncodedImageInterface + public function encodeByPath(?string $path = null, mixed ...$options): EncodedImageInterface { - return $this->encode(new FilePathEncoder($path, $quality)); + return $this->encode(new FilePathEncoder($path, ...$options)); } /** @@ -809,20 +809,20 @@ public function encodeByPath(?string $path = null, int $quality = 75): EncodedIm * * @see ImageInterface::toJpeg() */ - public function toJpeg(int $quality = 75): EncodedImageInterface + public function toJpeg(mixed ...$options): EncodedImageInterface { - return $this->encode(new JpegEncoder($quality)); + return $this->encode(new JpegEncoder(...$options)); } /** * Alias of self::toJpeg() * - * @param int $quality + * @param mixed $options * @return EncodedImageInterface */ - public function toJpg(int $quality = 75): EncodedImageInterface + public function toJpg(mixed ...$options): EncodedImageInterface { - return $this->toJpeg($quality); + return $this->toJpeg(...$options); } /** @@ -830,20 +830,20 @@ public function toJpg(int $quality = 75): EncodedImageInterface * * @see ImageInterface::toJpeg() */ - public function toJpeg2000(int $quality = 75): EncodedImageInterface + public function toJpeg2000(mixed ...$options): EncodedImageInterface { - return $this->encode(new Jpeg2000Encoder($quality)); + return $this->encode(new Jpeg2000Encoder(...$options)); } /** * ALias of self::toJpeg2000() * - * @param int $quality + * @param mixed $options * @return EncodedImageInterface */ - public function toJp2(int $quality = 75): EncodedImageInterface + public function toJp2(mixed ...$options): EncodedImageInterface { - return $this->toJpeg2000($quality); + return $this->toJpeg2000(...$options); } /** @@ -851,9 +851,9 @@ public function toJp2(int $quality = 75): EncodedImageInterface * * @see ImageInterface::toPng() */ - public function toPng(): EncodedImageInterface + public function toPng(mixed ...$options): EncodedImageInterface { - return $this->encode(new PngEncoder()); + return $this->encode(new PngEncoder(...$options)); } /** @@ -861,9 +861,9 @@ public function toPng(): EncodedImageInterface * * @see ImageInterface::toGif() */ - public function toGif(): EncodedImageInterface + public function toGif(mixed ...$options): EncodedImageInterface { - return $this->encode(new GifEncoder()); + return $this->encode(new GifEncoder(...$options)); } /** @@ -871,9 +871,9 @@ public function toGif(): EncodedImageInterface * * @see ImageInterface::toWebp() */ - public function toWebp(int $quality = 75): EncodedImageInterface + public function toWebp(mixed ...$options): EncodedImageInterface { - return $this->encode(new WebpEncoder($quality)); + return $this->encode(new WebpEncoder(...$options)); } /** @@ -881,9 +881,9 @@ public function toWebp(int $quality = 75): EncodedImageInterface * * @see ImageInterface::toBitmap() */ - public function toBitmap(): EncodedImageInterface + public function toBitmap(mixed ...$options): EncodedImageInterface { - return $this->encode(new BmpEncoder()); + return $this->encode(new BmpEncoder(...$options)); } /** @@ -891,9 +891,9 @@ public function toBitmap(): EncodedImageInterface * * @return EncodedImageInterface */ - public function toBmp(): EncodedImageInterface + public function toBmp(mixed ...$options): EncodedImageInterface { - return $this->toBitmap(); + return $this->toBitmap(...$options); } /** @@ -901,9 +901,9 @@ public function toBmp(): EncodedImageInterface * * @see ImageInterface::toAvif() */ - public function toAvif(int $quality = 75): EncodedImageInterface + public function toAvif(mixed ...$options): EncodedImageInterface { - return $this->encode(new AvifEncoder($quality)); + return $this->encode(new AvifEncoder(...$options)); } /** @@ -911,20 +911,20 @@ public function toAvif(int $quality = 75): EncodedImageInterface * * @see ImageInterface::toTiff() */ - public function toTiff(int $quality = 75): EncodedImageInterface + public function toTiff(mixed ...$options): EncodedImageInterface { - return $this->encode(new TiffEncoder($quality)); + return $this->encode(new TiffEncoder(...$options)); } /** * Alias of self::toTiff() * - * @param int $quality + * @param mixed $options * @return EncodedImageInterface */ - public function toTif(int $quality = 75): EncodedImageInterface + public function toTif(mixed ...$options): EncodedImageInterface { - return $this->toTiff($quality); + return $this->toTiff(...$options); } /** diff --git a/src/Interfaces/ImageInterface.php b/src/Interfaces/ImageInterface.php index 6b033a1e..e483f07d 100644 --- a/src/Interfaces/ImageInterface.php +++ b/src/Interfaces/ImageInterface.php @@ -74,7 +74,7 @@ public function encode(EncoderInterface $encoder): EncodedImageInterface; * @param null|string $path * @return ImageInterface */ - public function save(?string $path = null, int $quality = 75): ImageInterface; + public function save(?string $path = null, ...$options): ImageInterface; /** * Apply given modifier to current image @@ -573,7 +573,7 @@ public function drawLine(callable $init): ImageInterface; * @param null|string $type * @return EncodedImageInterface */ - public function encodeByMediaType(?string $type = null, int $quality = 75): EncodedImageInterface; + public function encodeByMediaType(?string $type = null, ...$options): EncodedImageInterface; /** * Encode the image into the format represented by the given extension. If no @@ -583,7 +583,7 @@ public function encodeByMediaType(?string $type = null, int $quality = 75): Enco * @param null|string $extension * @return EncodedImageInterface */ - public function encodeByExtension(?string $extension = null, int $quality = 75): EncodedImageInterface; + public function encodeByExtension(?string $extension = null, mixed ...$options): EncodedImageInterface; /** * Encode the image into the format represented by the given extension of @@ -593,66 +593,70 @@ public function encodeByExtension(?string $extension = null, int $quality = 75): * @param null|string $path * @return EncodedImageInterface */ - public function encodeByPath(?string $path = null, int $quality = 75): EncodedImageInterface; + public function encodeByPath(?string $path = null, mixed ...$options): EncodedImageInterface; /** * Encode image to JPEG format * - * @param int $quality + * @param mixed $options * @return EncodedImageInterface */ - public function toJpeg(int $quality = 75): EncodedImageInterface; + + public function toJpeg(mixed ...$options): EncodedImageInterface; /** * Encode image to Jpeg2000 format * - * @param int $quality + * @param mixed $options * @return EncodedImageInterface */ - public function toJpeg2000(int $quality = 75): EncodedImageInterface; + public function toJpeg2000(mixed ...$options): EncodedImageInterface; /** * Encode image to Webp format * - * @param int $quality + * @param mixed $options * @return EncodedImageInterface */ - public function toWebp(int $quality = 75): EncodedImageInterface; + public function toWebp(mixed ...$options): EncodedImageInterface; /** * Encode image to PNG format * + * @param mixed $options * @return EncodedImageInterface */ - public function toPng(): EncodedImageInterface; + public function toPng(mixed ...$options): EncodedImageInterface; /** * Encode image to GIF format * + * @param mixed $options * @return EncodedImageInterface */ - public function toGif(): EncodedImageInterface; + public function toGif(mixed ...$options): EncodedImageInterface; /** * Encode image to Bitmap format * + * @param mixed $options * @return EncodedImageInterface */ - public function toBitmap(): EncodedImageInterface; + public function toBitmap(mixed ...$options): EncodedImageInterface; /** * Encode image to AVIF format * - * @param int $quality + * @param mixed $options * @return EncodedImageInterface */ - public function toAvif(int $quality = 75): EncodedImageInterface; + public function toAvif(mixed ...$options): EncodedImageInterface; /** * Encode image to TIFF format * - * @param int $quality + * @param mixed $options * @return EncodedImageInterface */ - public function toTiff(int $quality = 75): EncodedImageInterface; + public function toTiff(mixed ...$options): EncodedImageInterface; } From 533278c9ea5f6bba1cbd5796a8239739bb67fbf5 Mon Sep 17 00:00:00 2001 From: Oliver Vogel Date: Wed, 10 Jan 2024 11:56:38 +0100 Subject: [PATCH 09/11] Add doc blocks --- src/Encoders/AbstractEncoder.php | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/Encoders/AbstractEncoder.php b/src/Encoders/AbstractEncoder.php index 72165f97..1bb8d1a5 100644 --- a/src/Encoders/AbstractEncoder.php +++ b/src/Encoders/AbstractEncoder.php @@ -12,8 +12,25 @@ abstract class AbstractEncoder implements EncoderInterface public const DEFAULT_COMPRESSION = 0; public const DEFAULT_BIT_DEPTH = 8; + /** + * Target quality of encoder + * + * @param int $quality + */ public int $quality = self::DEFAULT_QUALITY; + + /** + * Compression type of encoder + * + * @param int $compression + */ public int $compression = self::DEFAULT_COMPRESSION; + + /** + * Bit depth per channel at which the images are encoded + * + * @param int $bitDepth + */ public int $bitDepth = self::DEFAULT_BIT_DEPTH; /** From 284fbff79bbb7608558f5ac540534dc9e1ecfe9d Mon Sep 17 00:00:00 2001 From: Oliver Vogel Date: Thu, 11 Jan 2024 10:22:51 +0100 Subject: [PATCH 10/11] Remove compression type & bitDepth parameters for now --- src/Encoders/AbstractEncoder.php | 20 -------------------- 1 file changed, 20 deletions(-) diff --git a/src/Encoders/AbstractEncoder.php b/src/Encoders/AbstractEncoder.php index 1bb8d1a5..ab73c2f5 100644 --- a/src/Encoders/AbstractEncoder.php +++ b/src/Encoders/AbstractEncoder.php @@ -9,8 +9,6 @@ abstract class AbstractEncoder implements EncoderInterface { public const DEFAULT_QUALITY = 75; - public const DEFAULT_COMPRESSION = 0; - public const DEFAULT_BIT_DEPTH = 8; /** * Target quality of encoder @@ -19,20 +17,6 @@ abstract class AbstractEncoder implements EncoderInterface */ public int $quality = self::DEFAULT_QUALITY; - /** - * Compression type of encoder - * - * @param int $compression - */ - public int $compression = self::DEFAULT_COMPRESSION; - - /** - * Bit depth per channel at which the images are encoded - * - * @param int $bitDepth - */ - public int $bitDepth = self::DEFAULT_BIT_DEPTH; - /** * Create new encoder instance * @@ -43,12 +27,8 @@ public function __construct(mixed ...$options) { if (is_array($options) && array_is_list($options)) { $this->quality = $options[0] ?? self::DEFAULT_QUALITY; - $this->compression = $options[1] ?? self::DEFAULT_COMPRESSION; - $this->bitDepth = $options[2] ?? self::DEFAULT_BIT_DEPTH; } else { $this->quality = $options['quality'] ?? self::DEFAULT_QUALITY; - $this->compression = $options['compression'] ?? self::DEFAULT_COMPRESSION; - $this->bitDepth = $options['bitDepth'] ?? self::DEFAULT_BIT_DEPTH; } } From 96cc73f175b0e53d0cd45f3b71d18e34c8106e2d Mon Sep 17 00:00:00 2001 From: Oliver Vogel Date: Fri, 12 Jan 2024 09:17:32 +0100 Subject: [PATCH 11/11] Add named quality parameter in FileExtensionEncoder --- src/Encoders/FileExtensionEncoder.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Encoders/FileExtensionEncoder.php b/src/Encoders/FileExtensionEncoder.php index 58a67662..0f02607a 100644 --- a/src/Encoders/FileExtensionEncoder.php +++ b/src/Encoders/FileExtensionEncoder.php @@ -49,14 +49,14 @@ protected function encoderByFileExtension(?string $extension): EncoderInterface } return match (strtolower($extension)) { - 'webp' => new WebpEncoder($this->quality), - 'avif' => new AvifEncoder($this->quality), - 'jpeg', 'jpg' => new JpegEncoder($this->quality), + 'webp' => new WebpEncoder(quality: $this->quality), + 'avif' => new AvifEncoder(quality: $this->quality), + 'jpeg', 'jpg' => new JpegEncoder(quality: $this->quality), 'bmp' => new BmpEncoder(), 'gif' => new GifEncoder(), 'png' => new PngEncoder(), - 'tiff', 'tif' => new TiffEncoder($this->quality), - 'jp2', 'j2k', 'jpf', 'jpm', 'jpg2', 'j2c', 'jpc', 'jpx' => new Jpeg2000Encoder($this->quality), + 'tiff', 'tif' => new TiffEncoder(quality: $this->quality), + 'jp2', 'j2k', 'jpf', 'jpm', 'jpg2', 'j2c', 'jpc', 'jpx' => new Jpeg2000Encoder(quality: $this->quality), default => throw new EncoderException('No encoder found for file extension (' . $extension . ').'), }; }