diff --git a/src/Collection.php b/src/Collection.php index 4b27a669..10ac0618 100644 --- a/src/Collection.php +++ b/src/Collection.php @@ -13,7 +13,6 @@ class Collection implements CollectionInterface, IteratorAggregate, Countable { public function __construct(protected array $items = []) { - // } /** @@ -27,6 +26,11 @@ class Collection implements CollectionInterface, IteratorAggregate, Countable return new self($items); } + public function has(int|string $key): bool + { + return array_key_exists($key, $this->items); + } + /** * Returns Iterator * diff --git a/src/Colors/Cmyk/Decoders/StringColorDecoder.php b/src/Colors/Cmyk/Decoders/StringColorDecoder.php index 0f05ada9..7bfafbee 100644 --- a/src/Colors/Cmyk/Decoders/StringColorDecoder.php +++ b/src/Colors/Cmyk/Decoders/StringColorDecoder.php @@ -3,7 +3,7 @@ namespace Intervention\Image\Colors\Cmyk\Decoders; use Intervention\Image\Colors\Cmyk\Color; -use Intervention\Image\Drivers\Abstract\Decoders\AbstractDecoder; +use Intervention\Image\Drivers\AbstractDecoder; use Intervention\Image\Exceptions\DecoderException; use Intervention\Image\Interfaces\ColorInterface; use Intervention\Image\Interfaces\DecoderInterface; diff --git a/src/Colors/Profile.php b/src/Colors/Profile.php index b2b909a4..5e94823b 100644 --- a/src/Colors/Profile.php +++ b/src/Colors/Profile.php @@ -7,5 +7,4 @@ use Intervention\Image\Interfaces\ProfileInterface; class Profile extends GenericData implements ProfileInterface { - // } diff --git a/src/Colors/Rgb/Decoders/HexColorDecoder.php b/src/Colors/Rgb/Decoders/HexColorDecoder.php index 43aafee3..e00c14ba 100644 --- a/src/Colors/Rgb/Decoders/HexColorDecoder.php +++ b/src/Colors/Rgb/Decoders/HexColorDecoder.php @@ -3,7 +3,7 @@ namespace Intervention\Image\Colors\Rgb\Decoders; use Intervention\Image\Colors\Rgb\Color; -use Intervention\Image\Drivers\Abstract\Decoders\AbstractDecoder; +use Intervention\Image\Drivers\AbstractDecoder; use Intervention\Image\Exceptions\DecoderException; use Intervention\Image\Interfaces\ColorInterface; use Intervention\Image\Interfaces\DecoderInterface; diff --git a/src/Colors/Rgb/Decoders/StringColorDecoder.php b/src/Colors/Rgb/Decoders/StringColorDecoder.php index 86a62b4d..f262bb20 100644 --- a/src/Colors/Rgb/Decoders/StringColorDecoder.php +++ b/src/Colors/Rgb/Decoders/StringColorDecoder.php @@ -3,7 +3,7 @@ namespace Intervention\Image\Colors\Rgb\Decoders; use Intervention\Image\Colors\Rgb\Color; -use Intervention\Image\Drivers\Abstract\Decoders\AbstractDecoder; +use Intervention\Image\Drivers\AbstractDecoder; use Intervention\Image\Exceptions\DecoderException; use Intervention\Image\Interfaces\ColorInterface; use Intervention\Image\Interfaces\DecoderInterface; diff --git a/src/Drivers/Abstract/AbstractImage.php b/src/Drivers/Abstract/AbstractImage.php index 7fedf89e..5d8fbc89 100644 --- a/src/Drivers/Abstract/AbstractImage.php +++ b/src/Drivers/Abstract/AbstractImage.php @@ -19,7 +19,7 @@ use Intervention\Image\Traits\CanHandleInput; use Intervention\Image\Traits\CanResolveDriverClass; use Intervention\Image\Traits\CanRunCallback; -abstract class AbstractImage implements ImageInterface +abstract class DELETE___AbstractImage implements ImageInterface { use CanResolveDriverClass; use CanHandleInput; diff --git a/src/Drivers/Abstract/AbstractInputHandler.php b/src/Drivers/Abstract/AbstractInputHandler.php index 4fdbe951..62a127a9 100644 --- a/src/Drivers/Abstract/AbstractInputHandler.php +++ b/src/Drivers/Abstract/AbstractInputHandler.php @@ -8,7 +8,7 @@ use Intervention\Image\Interfaces\ColorInterface; use Intervention\Image\Interfaces\ImageInterface; use Intervention\Image\Interfaces\InputHandlerInterface; -abstract class AbstractInputHandler implements InputHandlerInterface +abstract class DELETE____AbstractInputHandler implements InputHandlerInterface { /** * Array of decoders which will be stacked into to the input handler chain diff --git a/src/Drivers/Abstract/Decoders/AbstractDecoder.php b/src/Drivers/Abstract/Decoders/AbstractDecoder.php index 27730f9c..a7182d13 100644 --- a/src/Drivers/Abstract/Decoders/AbstractDecoder.php +++ b/src/Drivers/Abstract/Decoders/AbstractDecoder.php @@ -9,7 +9,7 @@ use Intervention\Image\Interfaces\DecoderInterface; use Intervention\Image\Interfaces\ImageInterface; use Intervention\Image\Traits\CanBuildFilePointer; -abstract class AbstractDecoder implements DecoderInterface +abstract class DELETE___AbstractDecoder implements DecoderInterface { use CanBuildFilePointer; diff --git a/src/Drivers/Abstract/Modifiers/AbstractDrawModifier.php b/src/Drivers/Abstract/Modifiers/AbstractDrawModifier.php index 316abee9..ea1c09a2 100644 --- a/src/Drivers/Abstract/Modifiers/AbstractDrawModifier.php +++ b/src/Drivers/Abstract/Modifiers/AbstractDrawModifier.php @@ -14,18 +14,11 @@ use Intervention\Image\Interfaces\PointInterface; use Intervention\Image\Traits\CanCheckType; use Intervention\Image\Traits\CanHandleInput; -class AbstractDrawModifier +class DELETE__AbstractDrawModifier { use CanHandleInput; use CanCheckType; - public function __construct( - protected PointInterface $position, - protected DrawableInterface $drawable - ) { - // - } - public function drawable(): DrawableInterface { return $this->drawable; diff --git a/src/Drivers/Abstract/Modifiers/AbstractFitModifier.php b/src/Drivers/Abstract/Modifiers/AbstractFitModifier.php index cd845d62..988b955c 100644 --- a/src/Drivers/Abstract/Modifiers/AbstractFitModifier.php +++ b/src/Drivers/Abstract/Modifiers/AbstractFitModifier.php @@ -6,14 +6,13 @@ use Intervention\Image\Geometry\Rectangle; use Intervention\Image\Interfaces\ImageInterface; use Intervention\Image\Interfaces\SizeInterface; -abstract class AbstractFitModifier +abstract class DELETE___AbstractFitModifier { public function __construct( protected int $width, protected int $height, protected string $position = 'center' ) { - // } protected function getCropSize(ImageInterface $image): SizeInterface diff --git a/src/Drivers/Abstract/Modifiers/AbstractPadModifier.php b/src/Drivers/Abstract/Modifiers/AbstractPadModifier.php index 7a001e95..c5585f89 100644 --- a/src/Drivers/Abstract/Modifiers/AbstractPadModifier.php +++ b/src/Drivers/Abstract/Modifiers/AbstractPadModifier.php @@ -7,7 +7,7 @@ use Intervention\Image\Interfaces\ImageInterface; use Intervention\Image\Interfaces\SizeInterface; use Intervention\Image\Traits\CanCheckType; -abstract class AbstractPadModifier +abstract class DELETE___AbstractPadModifier { use CanCheckType; @@ -20,14 +20,14 @@ abstract class AbstractPadModifier // } - protected function getCropSize(ImageInterface $image): SizeInterface + public function getCropSize(ImageInterface $image): SizeInterface { return $image->size() ->contain($this->width, $this->height) ->alignPivotTo($this->getResizeSize($image), $this->position); } - protected function getResizeSize(ImageInterface $image): SizeInterface + public function getResizeSize(ImageInterface $image): SizeInterface { return new Rectangle($this->width, $this->height); } diff --git a/src/Drivers/Abstract/Modifiers/AbstractRemoveAnimationModifier.php b/src/Drivers/Abstract/Modifiers/AbstractRemoveAnimationModifier.php index e9a9099d..68d3455f 100644 --- a/src/Drivers/Abstract/Modifiers/AbstractRemoveAnimationModifier.php +++ b/src/Drivers/Abstract/Modifiers/AbstractRemoveAnimationModifier.php @@ -6,7 +6,7 @@ use Intervention\Image\Exceptions\InputException; use Intervention\Image\Interfaces\FrameInterface; use Intervention\Image\Interfaces\ModifierInterface; -abstract class AbstractRemoveAnimationModifier implements ModifierInterface +abstract class DELETE___AbstractRemoveAnimationModifier implements ModifierInterface { protected function chosenFrame($image, int|string $position): FrameInterface { diff --git a/src/Drivers/Abstract/Modifiers/AbstractRotateModifier.php b/src/Drivers/Abstract/Modifiers/AbstractRotateModifier.php index 113a4ba1..123e7c70 100644 --- a/src/Drivers/Abstract/Modifiers/AbstractRotateModifier.php +++ b/src/Drivers/Abstract/Modifiers/AbstractRotateModifier.php @@ -8,7 +8,7 @@ use Intervention\Image\Interfaces\ColorInterface; use Intervention\Image\Traits\CanCheckType; use Intervention\Image\Traits\CanHandleInput; -abstract class AbstractRotateModifier +abstract class DELETE____AbstractRotateModifier { use CanHandleInput; use CanCheckType; diff --git a/src/Drivers/AbstractDecoder.php b/src/Drivers/AbstractDecoder.php new file mode 100644 index 00000000..569467b5 --- /dev/null +++ b/src/Drivers/AbstractDecoder.php @@ -0,0 +1,155 @@ +decode($input); + } catch (DecoderException $e) { + if (!$this->hasSuccessor()) { + throw new DecoderException($e->getMessage()); + } + + return $this->successor->handle($input); + } + + return $decoded; + } + + protected function hasSuccessor(): bool + { + return $this->successor !== null; + } + + /** + * Return media type (MIME) of given input + * + * @param string $input + * @return string + */ + protected function mediaType(string $input): string + { + $pointer = $this->buildFilePointer($input); + $type = mime_content_type($pointer); + fclose($pointer); + + return $type; + } + + protected function decodeExifData(string $image_data): CollectionInterface + { + if (!function_exists('exif_read_data')) { + return []; + } + + try { + $pointer = $this->buildFilePointer($image_data); + $data = @exif_read_data($pointer, null, true); + fclose($pointer); + } catch (Exception $e) { + $data = []; + } + + return new Collection(is_array($data) ? $data : []); + } + + protected function isValidBase64($input): bool + { + if (!is_string($input)) { + return false; + } + + return base64_encode(base64_decode($input)) === str_replace(["\n", "\r"], '', $input); + } + + /** + * Parse data uri + * + * @param mixed $value + * @return object + */ + protected function parseDataUri($value): object + { + $pattern = "/^data:(?P\w+\/[-+.\w]+)?" . + "(?P(;[-\w]+=[-\w]+)*)(?P;base64)?,(?P.*)/"; + + $result = preg_match($pattern, $value, $matches); + + return new class ($matches, $result) + { + private $matches; + private $result; + + public function __construct($matches, $result) + { + $this->matches = $matches; + $this->result = $result; + } + + public function isValid(): bool + { + return (bool) $this->result; + } + + public function mediaType(): ?string + { + if (isset($this->matches['mediatype']) && !empty($this->matches['mediatype'])) { + return $this->matches['mediatype']; + } + + return null; + } + + public function hasMediaType(): bool + { + return !empty($this->mediaType()); + } + + public function parameters(): array + { + if (isset($this->matches['parameters']) && !empty($this->matches['parameters'])) { + return explode(';', trim($this->matches['parameters'], ';')); + } + + return []; + } + + public function isBase64Encoded(): bool + { + if (isset($this->matches['base64']) && $this->matches['base64'] === ';base64') { + return true; + } + + return false; + } + + public function data(): ?string + { + if (isset($this->matches['data']) && !empty($this->matches['data'])) { + return $this->matches['data']; + } + + return null; + } + }; + } +} diff --git a/src/Drivers/AbstractDriver.php b/src/Drivers/AbstractDriver.php new file mode 100644 index 00000000..6a4ac9b2 --- /dev/null +++ b/src/Drivers/AbstractDriver.php @@ -0,0 +1,33 @@ +getNamespaceName(); + $classname = (new ReflectionClass($input))->getShortName(); + + preg_match("/(?P[A-Z][a-z]+)$/", $classname, $matches); + $department = array_key_exists('dept', $matches) ? $matches['dept'] : null; + $department = match ($department) { + 'Modifier', 'Writer' => 'Modifiers', + 'Encoder' => 'Encoders', + default => null, + }; + + $specialized = implode("\\", array_filter([ + $ns, + $department, + $classname + ], function ($dept) { + return !empty($dept); + })); + + return new $specialized($input, $this); + } +} diff --git a/src/Drivers/Abstract/AbstractFont.php b/src/Drivers/AbstractFont.php similarity index 98% rename from src/Drivers/Abstract/AbstractFont.php rename to src/Drivers/AbstractFont.php index 678285eb..feed08cd 100644 --- a/src/Drivers/Abstract/AbstractFont.php +++ b/src/Drivers/AbstractFont.php @@ -1,6 +1,6 @@ decoders = count($decoders) ? $decoders : $this->decoders; + } + + /** + * {@inheritdoc} + * + * @see InputHandlerInterface::handle() + */ + public function handle($input): ImageInterface|ColorInterface + { + return $this->chain()->handle($input); + } + + /** + * Stack the decoder array into a nested decoder object + * + * @return AbstractDecoder + */ + protected function chain(): AbstractDecoder + { + if (count($this->decoders) == 0) { + throw new DecoderException('No decoders found in ' . get_class($this)); + } + + // get instance of last decoder in stack + list($classname) = array_slice(array_reverse($this->decoders), 0, 1); + $chain = new $classname(); + + // build decoder chain + foreach (array_slice(array_reverse($this->decoders), 1) as $classname) { + $chain = new $classname($chain); + } + + return $chain; + } +} diff --git a/src/Drivers/DrawModifier.php b/src/Drivers/DrawModifier.php new file mode 100644 index 00000000..8a4ed9c5 --- /dev/null +++ b/src/Drivers/DrawModifier.php @@ -0,0 +1,37 @@ +drawable->pivot(); + } + + public function backgroundColor(): ColorInterface + { + try { + $color = $this->driver()->handleInput($this->drawable->backgroundColor()); + } catch (DecoderException $e) { + return $this->driver()->handleInput('transparent'); + } + + return $color; + } + + public function borderColor(): ColorInterface + { + try { + $color = $this->driver()->handleInput($this->drawable->borderColor()); + } catch (DecoderException $e) { + return $this->driver()->handleInput('transparent'); + } + + return $color; + } +} diff --git a/src/Drivers/DriverEncoder.php b/src/Drivers/DriverEncoder.php new file mode 100644 index 00000000..7ee6fb9e --- /dev/null +++ b/src/Drivers/DriverEncoder.php @@ -0,0 +1,47 @@ +driver; + } + + /** + * Magic method to read attributes of underlying endcoder + * + * @param string $name + * @return mixed + */ + public function __get(string $name): mixed + { + return $this->encoder->$name; + } + + /** + * Get return value of callback through output buffer + * + * @param callable $callback + * @return string + */ + protected function getBuffered(callable $callback): string + { + ob_start(); + $callback(); + $buffer = ob_get_contents(); + ob_end_clean(); + + return $buffer; + } +} diff --git a/src/Drivers/DriverModifier.php b/src/Drivers/DriverModifier.php new file mode 100644 index 00000000..3722f2e4 --- /dev/null +++ b/src/Drivers/DriverModifier.php @@ -0,0 +1,43 @@ +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/Drivers/Gd/ColorProcessor.php b/src/Drivers/Gd/ColorProcessor.php new file mode 100644 index 00000000..a2e019f4 --- /dev/null +++ b/src/Drivers/Gd/ColorProcessor.php @@ -0,0 +1,54 @@ +channel(Red::class)->value(); + $g = $color->channel(Green::class)->value(); + $b = $color->channel(Blue::class)->value(); + $a = $color->channel(Alpha::class)->value(); + + // convert alpha value to gd alpha + // ([opaque]255-0[transparent]) to ([opaque]0-127[transparent]) + $a = (int) $this->convertRange($a, 0, 255, 127, 0); + + return ($a << 24) + ($r << 16) + ($g << 8) + $b; + } + + /** + * Convert input in range (min) to (max) to the corresponding value + * in target range (targetMin) to (targetMax). + * + * @param float|int $input + * @param float|int $min + * @param float|int $max + * @param float|int $targetMin + * @param float|int $targetMax + * @return float|int + */ + protected function convertRange( + float|int $input, + float|int $min, + float|int $max, + float|int $targetMin, + float|int $targetMax + ): float|int { + return ceil(((($input - $min) * ($targetMax - $targetMin)) / ($max - $min)) + $targetMin); + } +} diff --git a/src/Drivers/Gd/Core.php b/src/Drivers/Gd/Core.php new file mode 100644 index 00000000..fabc4ec4 --- /dev/null +++ b/src/Drivers/Gd/Core.php @@ -0,0 +1,51 @@ +first()->data(); + } + + public function width(): int + { + return imagesx($this->native()); + } + + public function height(): int + { + return imagesy($this->native()); + } + + public function frame(int $position): FrameInterface + { + return $this->getAtPosition($position); + } + + public function loops(): int + { + return $this->loops; + } + + public function setLoops(int $loops): self + { + $this->loops = $loops; + + return $this; + } + + public function colorspace(): ColorspaceInterface + { + return new RgbColorspace(); + } +} diff --git a/src/Drivers/Gd/Decoders/BinaryImageDecoder.php b/src/Drivers/Gd/Decoders/BinaryImageDecoder.php index 5fe4bf5b..a61a18eb 100644 --- a/src/Drivers/Gd/Decoders/BinaryImageDecoder.php +++ b/src/Drivers/Gd/Decoders/BinaryImageDecoder.php @@ -2,17 +2,17 @@ namespace Intervention\Image\Drivers\Gd\Decoders; -use GdImage; -use Intervention\Image\Collection; -use Intervention\Image\Drivers\Abstract\Decoders\AbstractDecoder; +use Intervention\Image\Drivers\AbstractDecoder; use Intervention\Image\Drivers\Gd\Frame; -use Intervention\Image\Drivers\Gd\Image; use Intervention\Image\Interfaces\ColorInterface; use Intervention\Image\Interfaces\DecoderInterface; use Intervention\Image\Interfaces\ImageInterface; use Intervention\Gif\Decoder as GifDecoder; use Intervention\Gif\Splitter as GifSplitter; +use Intervention\Image\Drivers\Gd\Core; +use Intervention\Image\Drivers\Gd\Driver; use Intervention\Image\Exceptions\DecoderException; +use Intervention\Image\Image; class BinaryImageDecoder extends AbstractDecoder implements DecoderInterface { @@ -26,40 +26,45 @@ class BinaryImageDecoder extends AbstractDecoder implements DecoderInterface return $this->decodeGif($input); // decode (animated) gif } - $gd = $this->coreFromString($input); - // build image instance - $image = new Image(new Collection([new Frame($gd)])); - $image->setExif($this->decodeExifData($input)); + $image = new Image( + new Driver(), + $this->coreFromString($input), + $this->decodeExifData($input) + ); + + return $image; // fix image orientation - return match ($image->exif('IFD0.Orientation')) { - 2 => $image->flip(), - 3 => $image->rotate(180), - 4 => $image->rotate(180)->flip(), - 5 => $image->rotate(270)->flip(), - 6 => $image->rotate(270), - 7 => $image->rotate(90)->flip(), - 8 => $image->rotate(90), - default => $image - }; + // return match ($image->exif('IFD0.Orientation')) { + // 2 => $image->flip(), + // 3 => $image->rotate(180), + // 4 => $image->rotate(180)->flip(), + // 5 => $image->rotate(270)->flip(), + // 6 => $image->rotate(270), + // 7 => $image->rotate(90)->flip(), + // 8 => $image->rotate(90), + // default => $image + // }; } - private function coreFromString(string $input): GdImage + private function coreFromString(string $input): Core { - $gd = @imagecreatefromstring($input); + $data = @imagecreatefromstring($input); - if ($gd === false) { + if ($data === false) { throw new DecoderException('Unable to decode input'); } - if (!imageistruecolor($gd)) { - imagepalettetotruecolor($gd); + if (!imageistruecolor($data)) { + imagepalettetotruecolor($data); } - imagesavealpha($gd, true); + imagesavealpha($data, true); - return $gd; + return new Core([ + new Frame($data) + ]); } private function decodeGif(string $input): ImageInterface @@ -68,22 +73,26 @@ class BinaryImageDecoder extends AbstractDecoder implements DecoderInterface if (!$gif->isAnimated()) { return new Image( - new Collection([new Frame( - $this->coreFromString($input) - )]), + new Driver(), + $this->coreFromString($input) ); } - $image = new Image(new Collection()); - $image->setLoops($gif->getMainApplicationExtension()?->getLoops()); - $splitter = GifSplitter::create($gif)->split(); - $delays = $splitter->getDelays(); - foreach ($splitter->coalesceToResources() as $key => $gd) { - $image->addFrame((new Frame($gd))->setDelay($delays[$key] / 100)); + + // build core + $core = new Core(); + $core->setLoops($gif->getMainApplicationExtension()?->getLoops()); + foreach ($splitter->coalesceToResources() as $key => $data) { + $core->push( + (new Frame($data))->setDelay($delays[$key] / 100) + ); } - return $image; + return new Image( + new Driver(), + $core + ); } } diff --git a/src/Drivers/Gd/Decoders/ColorObjectDecoder.php b/src/Drivers/Gd/Decoders/ColorObjectDecoder.php index 7c2e83a4..5dd821d9 100644 --- a/src/Drivers/Gd/Decoders/ColorObjectDecoder.php +++ b/src/Drivers/Gd/Decoders/ColorObjectDecoder.php @@ -2,7 +2,7 @@ namespace Intervention\Image\Drivers\Gd\Decoders; -use Intervention\Image\Drivers\Abstract\Decoders\AbstractDecoder; +use Intervention\Image\Drivers\AbstractDecoder; use Intervention\Image\Exceptions\DecoderException; use Intervention\Image\Interfaces\ColorInterface; use Intervention\Image\Interfaces\DecoderInterface; diff --git a/src/Drivers/Gd/Decoders/ImageObjectDecoder.php b/src/Drivers/Gd/Decoders/ImageObjectDecoder.php index 72851dd8..248515a4 100644 --- a/src/Drivers/Gd/Decoders/ImageObjectDecoder.php +++ b/src/Drivers/Gd/Decoders/ImageObjectDecoder.php @@ -2,7 +2,7 @@ namespace Intervention\Image\Drivers\Gd\Decoders; -use Intervention\Image\Drivers\Abstract\Decoders\AbstractDecoder; +use Intervention\Image\Drivers\AbstractDecoder; use Intervention\Image\Exceptions\DecoderException; use Intervention\Image\Interfaces\ColorInterface; use Intervention\Image\Interfaces\DecoderInterface; diff --git a/src/Drivers/Gd/Driver.php b/src/Drivers/Gd/Driver.php new file mode 100644 index 00000000..bb25729a --- /dev/null +++ b/src/Drivers/Gd/Driver.php @@ -0,0 +1,40 @@ +handle($input); + } + + public function colorToNative(ColorInterface $color, ColorspaceInterface $colorspace): mixed + { + return (new ColorProcessor($colorspace))->colorToNative($color); + } +} diff --git a/src/Drivers/Gd/Element.php b/src/Drivers/Gd/Element.php new file mode 100644 index 00000000..185c03e2 --- /dev/null +++ b/src/Drivers/Gd/Element.php @@ -0,0 +1,9 @@ +quality = $quality; - } - public function encode(ImageInterface $image): EncodedImage { - $data = $this->getBuffered(function () use ($image) { - imageavif($image->frame()->core(), null, $this->quality); + $gd = $image->core()->native(); + $data = $this->getBuffered(function () use ($gd) { + imageavif($gd, null, $this->quality); }); return new EncodedImage($data, 'image/avif'); diff --git a/src/Drivers/Gd/Encoders/BmpEncoder.php b/src/Drivers/Gd/Encoders/BmpEncoder.php index a3e95b40..8cae8852 100644 --- a/src/Drivers/Gd/Encoders/BmpEncoder.php +++ b/src/Drivers/Gd/Encoders/BmpEncoder.php @@ -2,24 +2,19 @@ namespace Intervention\Image\Drivers\Gd\Encoders; -use Intervention\Image\Drivers\Abstract\Encoders\AbstractEncoder; -use Intervention\Image\Drivers\Gd\Modifiers\LimitColorsModifier; +use Intervention\Image\Drivers\DriverEncoder; +use Intervention\Image\Modifiers\LimitColorsModifier; use Intervention\Image\EncodedImage; -use Intervention\Image\Interfaces\EncoderInterface; use Intervention\Image\Interfaces\ImageInterface; -class BmpEncoder extends AbstractEncoder implements EncoderInterface +class BmpEncoder extends DriverEncoder { - public function __construct(protected int $color_limit = 0) - { - // - } - public function encode(ImageInterface $image): EncodedImage { $image = $image->modify(new LimitColorsModifier($this->color_limit)); - $data = $this->getBuffered(function () use ($image) { - imagebmp($image->frame()->core(), null, false); + $gd = $image->core()->native(); + $data = $this->getBuffered(function () use ($gd) { + imagebmp($gd, null, false); }); return new EncodedImage($data, 'image/bmp'); diff --git a/src/Drivers/Gd/Encoders/GifEncoder.php b/src/Drivers/Gd/Encoders/GifEncoder.php index 5967f5cd..b54727d1 100644 --- a/src/Drivers/Gd/Encoders/GifEncoder.php +++ b/src/Drivers/Gd/Encoders/GifEncoder.php @@ -3,19 +3,13 @@ namespace Intervention\Image\Drivers\Gd\Encoders; use Intervention\Gif\Builder as GifBuilder; -use Intervention\Image\Drivers\Abstract\Encoders\AbstractEncoder; -use Intervention\Image\Drivers\Gd\Modifiers\LimitColorsModifier; +use Intervention\Image\Drivers\DriverEncoder; +use Intervention\Image\Modifiers\LimitColorsModifier; use Intervention\Image\EncodedImage; -use Intervention\Image\Interfaces\EncoderInterface; use Intervention\Image\Interfaces\ImageInterface; -class GifEncoder extends AbstractEncoder implements EncoderInterface +class GifEncoder extends DriverEncoder { - public function __construct(protected int $color_limit = 0) - { - // - } - public function encode(ImageInterface $image): EncodedImage { if ($image->isAnimated()) { @@ -23,8 +17,9 @@ class GifEncoder extends AbstractEncoder implements EncoderInterface } $image = $image->modify(new LimitColorsModifier($this->color_limit)); - $data = $this->getBuffered(function () use ($image) { - imagegif($image->frame()->core()); + $gd = $image->core()->native(); + $data = $this->getBuffered(function () use ($gd) { + imagegif($gd); }); return new EncodedImage($data, 'image/gif'); @@ -40,7 +35,7 @@ class GifEncoder extends AbstractEncoder implements EncoderInterface foreach ($image as $frame) { $builder->addFrame( - $this->encode($frame->toImage()), + $this->encode($frame->toImage($image->driver())), $frame->delay() ); } diff --git a/src/Drivers/Gd/Encoders/JpegEncoder.php b/src/Drivers/Gd/Encoders/JpegEncoder.php index 7ceff33f..a1ff5cda 100644 --- a/src/Drivers/Gd/Encoders/JpegEncoder.php +++ b/src/Drivers/Gd/Encoders/JpegEncoder.php @@ -2,22 +2,17 @@ namespace Intervention\Image\Drivers\Gd\Encoders; -use Intervention\Image\Drivers\Abstract\Encoders\AbstractEncoder; +use Intervention\Image\Drivers\DriverEncoder; use Intervention\Image\EncodedImage; -use Intervention\Image\Interfaces\EncoderInterface; use Intervention\Image\Interfaces\ImageInterface; -class JpegEncoder extends AbstractEncoder implements EncoderInterface +class JpegEncoder extends DriverEncoder { - public function __construct(int $quality) - { - $this->quality = $quality; - } - public function encode(ImageInterface $image): EncodedImage { - $data = $this->getBuffered(function () use ($image) { - imagejpeg($image->frame()->core(), null, $this->quality); + $gd = $image->core()->native(); + $data = $this->getBuffered(function () use ($gd) { + imagejpeg($gd, null, $this->quality); }); return new EncodedImage($data, 'image/jpeg'); diff --git a/src/Drivers/Gd/Encoders/PngEncoder.php b/src/Drivers/Gd/Encoders/PngEncoder.php index 7daa2dc6..360f7525 100644 --- a/src/Drivers/Gd/Encoders/PngEncoder.php +++ b/src/Drivers/Gd/Encoders/PngEncoder.php @@ -2,24 +2,19 @@ namespace Intervention\Image\Drivers\Gd\Encoders; -use Intervention\Image\Drivers\Abstract\Encoders\AbstractEncoder; -use Intervention\Image\Drivers\Gd\Modifiers\LimitColorsModifier; +use Intervention\Image\Drivers\DriverEncoder; use Intervention\Image\EncodedImage; -use Intervention\Image\Interfaces\EncoderInterface; use Intervention\Image\Interfaces\ImageInterface; +use Intervention\Image\Modifiers\LimitColorsModifier; -class PngEncoder extends AbstractEncoder implements EncoderInterface +class PngEncoder extends DriverEncoder { - public function __construct(protected int $color_limit = 0) - { - // - } - public function encode(ImageInterface $image): EncodedImage { $image = $image->modify(new LimitColorsModifier($this->color_limit)); - $data = $this->getBuffered(function () use ($image) { - imagepng($image->frame()->core(), null, -1); + $gd = $image->core()->native(); + $data = $this->getBuffered(function () use ($gd) { + imagepng($gd, null, -1); }); return new EncodedImage($data, 'image/png'); diff --git a/src/Drivers/Gd/Encoders/WebpEncoder.php b/src/Drivers/Gd/Encoders/WebpEncoder.php index 7efd63ce..d0fde05d 100644 --- a/src/Drivers/Gd/Encoders/WebpEncoder.php +++ b/src/Drivers/Gd/Encoders/WebpEncoder.php @@ -2,22 +2,17 @@ namespace Intervention\Image\Drivers\Gd\Encoders; -use Intervention\Image\Drivers\Abstract\Encoders\AbstractEncoder; +use Intervention\Image\Drivers\DriverEncoder; use Intervention\Image\EncodedImage; -use Intervention\Image\Interfaces\EncoderInterface; use Intervention\Image\Interfaces\ImageInterface; -class WebpEncoder extends AbstractEncoder implements EncoderInterface +class WebpEncoder extends DriverEncoder { - public function __construct(int $quality) - { - $this->quality = $quality; - } - public function encode(ImageInterface $image): EncodedImage { - $data = $this->getBuffered(function () use ($image) { - imagewebp($image->frame()->core(), null, $this->quality); + $gd = $image->core()->native(); + $data = $this->getBuffered(function () use ($gd) { + imagewebp($gd, null, $this->quality); }); return new EncodedImage($data, 'image/webp'); diff --git a/src/Drivers/Gd/Factory.php b/src/Drivers/Gd/Factory.php index d4a6fee4..f429eb6b 100644 --- a/src/Drivers/Gd/Factory.php +++ b/src/Drivers/Gd/Factory.php @@ -12,7 +12,7 @@ use Intervention\Image\Interfaces\FactoryInterface; use Intervention\Image\Interfaces\ImageInterface; use Intervention\Image\Traits\CanHandleInput; -class Factory implements FactoryInterface +class DELETE___Factory implements FactoryInterface { use CanHandleInput; use CanHandleColors; diff --git a/src/Drivers/Gd/Font.php b/src/Drivers/Gd/Font.php index 21cf3f24..68370808 100644 --- a/src/Drivers/Gd/Font.php +++ b/src/Drivers/Gd/Font.php @@ -2,7 +2,7 @@ namespace Intervention\Image\Drivers\Gd; -use Intervention\Image\Drivers\Abstract\AbstractFont; +use Intervention\Image\Drivers\AbstractFont; use Intervention\Image\Geometry\Point; use Intervention\Image\Geometry\Polygon; use Intervention\Image\Geometry\Rectangle; diff --git a/src/Drivers/Gd/Frame.php b/src/Drivers/Gd/Frame.php index cf4dcce7..637f2e43 100644 --- a/src/Drivers/Gd/Frame.php +++ b/src/Drivers/Gd/Frame.php @@ -3,8 +3,9 @@ namespace Intervention\Image\Drivers\Gd; use GdImage; -use Intervention\Image\Collection; use Intervention\Image\Geometry\Rectangle; +use Intervention\Image\Image; +use Intervention\Image\Interfaces\DriverInterface; use Intervention\Image\Interfaces\FrameInterface; use Intervention\Image\Interfaces\ImageInterface; use Intervention\Image\Interfaces\SizeInterface; @@ -12,7 +13,7 @@ use Intervention\Image\Interfaces\SizeInterface; class Frame implements FrameInterface { public function __construct( - protected GdImage $core, + protected GdImage $data, protected float $delay = 0, protected int $dispose = 1, protected int $offset_left = 0, @@ -21,26 +22,31 @@ class Frame implements FrameInterface // } - public function setCore($core): FrameInterface + public function toImage(DriverInterface $driver): ImageInterface { - $this->core = $core; + return new Image($driver, new Core([$this])); + } + + public function setData($data): FrameInterface + { + $this->data = $data; return $this; } - public function core(): GdImage + public function data(): GdImage { - return $this->core; + return $this->data; } - public function unsetCore(): void + public function unsetData(): void { - unset($this->core); + unset($this->data); } public function size(): SizeInterface { - return new Rectangle(imagesx($this->core), imagesy($this->core)); + return new Rectangle(imagesx($this->data), imagesy($this->data)); } public function delay(): float @@ -98,9 +104,4 @@ class Frame implements FrameInterface return $this; } - - public function toImage(): ImageInterface - { - return new Image(new Collection([$this])); - } } diff --git a/src/Drivers/Gd/Image.php b/src/Drivers/Gd/Image.php index 1c32102b..2f2a56ba 100644 --- a/src/Drivers/Gd/Image.php +++ b/src/Drivers/Gd/Image.php @@ -19,7 +19,7 @@ use Intervention\Image\Resolution; use IteratorAggregate; use Traversable; -class Image extends AbstractImage implements ImageInterface, IteratorAggregate +class DELETE__Image extends AbstractImage implements ImageInterface, IteratorAggregate { use CanHandleColors; diff --git a/src/Drivers/Gd/InputHandler.php b/src/Drivers/Gd/InputHandler.php index 0a484b8a..758b9d1f 100644 --- a/src/Drivers/Gd/InputHandler.php +++ b/src/Drivers/Gd/InputHandler.php @@ -7,7 +7,7 @@ use Intervention\Image\Colors\Rgb\Decoders\StringColorDecoder as RgbStringColorD use Intervention\Image\Colors\Rgb\Decoders\HtmlColornameDecoder; use Intervention\Image\Colors\Rgb\Decoders\TransparentColorDecoder; use Intervention\Image\Colors\Cmyk\Decoders\StringColorDecoder as CmykStringColorDecoder; -use Intervention\Image\Drivers\Abstract\AbstractInputHandler; +use Intervention\Image\Drivers\AbstractInputHandler; use Intervention\Image\Drivers\Gd\Decoders\ImageObjectDecoder; use Intervention\Image\Drivers\Gd\Decoders\ColorObjectDecoder; use Intervention\Image\Drivers\Gd\Decoders\FilePointerImageDecoder; diff --git a/src/Drivers/Gd/Modifiers/BlurModifier.php b/src/Drivers/Gd/Modifiers/BlurModifier.php index 63f87dda..0cd5675b 100644 --- a/src/Drivers/Gd/Modifiers/BlurModifier.php +++ b/src/Drivers/Gd/Modifiers/BlurModifier.php @@ -2,30 +2,19 @@ namespace Intervention\Image\Drivers\Gd\Modifiers; -use Intervention\Image\Interfaces\FrameInterface; +use Intervention\Image\Drivers\DriverModifier; use Intervention\Image\Interfaces\ImageInterface; -use Intervention\Image\Interfaces\ModifierInterface; -class BlurModifier implements ModifierInterface +class BlurModifier extends DriverModifier { - public function __construct(protected int $amount) - { - // - } - public function apply(ImageInterface $image): ImageInterface { foreach ($image as $frame) { - $this->blurFrame($frame); + for ($i = 0; $i < $this->amount; $i++) { + imagefilter($frame->data(), IMG_FILTER_GAUSSIAN_BLUR); + } } return $image; } - - protected function blurFrame(FrameInterface $frame): void - { - for ($i = 0; $i < $this->amount; $i++) { - imagefilter($frame->core(), IMG_FILTER_GAUSSIAN_BLUR); - } - } } diff --git a/src/Drivers/Gd/Modifiers/BrightnessModifier.php b/src/Drivers/Gd/Modifiers/BrightnessModifier.php index b0b4980a..05f7d62d 100644 --- a/src/Drivers/Gd/Modifiers/BrightnessModifier.php +++ b/src/Drivers/Gd/Modifiers/BrightnessModifier.php @@ -2,20 +2,15 @@ namespace Intervention\Image\Drivers\Gd\Modifiers; +use Intervention\Image\Drivers\DriverModifier; use Intervention\Image\Interfaces\ImageInterface; -use Intervention\Image\Interfaces\ModifierInterface; -class BrightnessModifier implements ModifierInterface +class BrightnessModifier extends DriverModifier { - public function __construct(protected int $level) - { - // - } - public function apply(ImageInterface $image): ImageInterface { foreach ($image as $frame) { - imagefilter($frame->core(), IMG_FILTER_BRIGHTNESS, intval($this->level * 2.55)); + imagefilter($frame->data(), IMG_FILTER_BRIGHTNESS, intval($this->level * 2.55)); } return $image; diff --git a/src/Drivers/Gd/Modifiers/ColorizeModifier.php b/src/Drivers/Gd/Modifiers/ColorizeModifier.php index 6a55f245..2a57ecdc 100644 --- a/src/Drivers/Gd/Modifiers/ColorizeModifier.php +++ b/src/Drivers/Gd/Modifiers/ColorizeModifier.php @@ -2,19 +2,11 @@ namespace Intervention\Image\Drivers\Gd\Modifiers; +use Intervention\Image\Drivers\DriverModifier; use Intervention\Image\Interfaces\ImageInterface; -use Intervention\Image\Interfaces\ModifierInterface; -class ColorizeModifier implements ModifierInterface +class ColorizeModifier extends DriverModifier { - public function __construct( - protected int $red = 0, - protected int $green = 0, - protected int $blue = 0 - ) { - // - } - public function apply(ImageInterface $image): ImageInterface { // normalize colorize levels @@ -23,7 +15,7 @@ class ColorizeModifier implements ModifierInterface $blue = round($this->blue * 2.55); foreach ($image as $frame) { - imagefilter($frame->core(), IMG_FILTER_COLORIZE, $red, $green, $blue); + imagefilter($frame->data(), IMG_FILTER_COLORIZE, $red, $green, $blue); } return $image; diff --git a/src/Drivers/Gd/Modifiers/ColorspaceModifier.php b/src/Drivers/Gd/Modifiers/ColorspaceModifier.php new file mode 100644 index 00000000..f580fe62 --- /dev/null +++ b/src/Drivers/Gd/Modifiers/ColorspaceModifier.php @@ -0,0 +1,22 @@ +targetColorspace(), RgbColorspace::class)) { + throw new NotSupportedException( + 'Only RGB colorspace is supported with GD driver.' + ); + } + + return $image; + } +} diff --git a/src/Drivers/Gd/Modifiers/ContrastModifier.php b/src/Drivers/Gd/Modifiers/ContrastModifier.php index 6a0a0755..7c97cb6d 100644 --- a/src/Drivers/Gd/Modifiers/ContrastModifier.php +++ b/src/Drivers/Gd/Modifiers/ContrastModifier.php @@ -2,20 +2,15 @@ namespace Intervention\Image\Drivers\Gd\Modifiers; +use Intervention\Image\Drivers\DriverModifier; use Intervention\Image\Interfaces\ImageInterface; -use Intervention\Image\Interfaces\ModifierInterface; -class ContrastModifier implements ModifierInterface +class ContrastModifier extends DriverModifier { - public function __construct(protected int $level) - { - // - } - public function apply(ImageInterface $image): ImageInterface { foreach ($image as $frame) { - imagefilter($frame->core(), IMG_FILTER_CONTRAST, ($this->level * -1)); + imagefilter($frame->data(), IMG_FILTER_CONTRAST, ($this->level * -1)); } return $image; diff --git a/src/Drivers/Gd/Modifiers/CropModifier.php b/src/Drivers/Gd/Modifiers/CropModifier.php index f992ca65..a15f8e94 100644 --- a/src/Drivers/Gd/Modifiers/CropModifier.php +++ b/src/Drivers/Gd/Modifiers/CropModifier.php @@ -2,32 +2,16 @@ namespace Intervention\Image\Drivers\Gd\Modifiers; -use Intervention\Image\Geometry\Rectangle; +use Intervention\Image\Drivers\DriverModifier; use Intervention\Image\Interfaces\FrameInterface; use Intervention\Image\Interfaces\ImageInterface; -use Intervention\Image\Interfaces\ModifierInterface; use Intervention\Image\Interfaces\SizeInterface; -use Intervention\Image\Traits\CanBuildNewImage; -class CropModifier implements ModifierInterface +class CropModifier extends DriverModifier { - use CanBuildNewImage; - - public function __construct( - protected int $width, - protected int $height, - protected int $offset_x = 0, - protected int $offset_y = 0, - protected string $position = 'top-left' - ) { - // - } - public function apply(ImageInterface $image): ImageInterface { - $crop = new Rectangle($this->width, $this->height); - $crop->align($this->position); - $crop->alignPivotTo($image->size(), $this->position); + $crop = $this->crop($image); foreach ($image as $frame) { $this->cropFrame($frame, $crop); @@ -39,13 +23,13 @@ class CropModifier implements ModifierInterface protected function cropFrame(FrameInterface $frame, SizeInterface $resizeTo): void { // create new image - $modified = $this->imageFactory()->newCore( - $resizeTo->width(), - $resizeTo->height() - ); + $modified = $this->driver() + ->createImage($resizeTo->width(), $resizeTo->height()) + ->core() + ->native(); // get original image - $original = $frame->core(); + $original = $frame->data(); // preserve transparency $transIndex = imagecolortransparent($original); @@ -72,6 +56,6 @@ class CropModifier implements ModifierInterface ); // set new content as recource - $frame->setCore($modified); + $frame->setData($modified); } } diff --git a/src/Drivers/Gd/Modifiers/DestroyModifier.php b/src/Drivers/Gd/Modifiers/DestroyModifier.php deleted file mode 100644 index 2ea95416..00000000 --- a/src/Drivers/Gd/Modifiers/DestroyModifier.php +++ /dev/null @@ -1,18 +0,0 @@ -unsetCore(); - } - - return $image; - } -} diff --git a/src/Drivers/Gd/Modifiers/DrawEllipseModifier.php b/src/Drivers/Gd/Modifiers/DrawEllipseModifier.php index 8e29eb63..974c50d1 100644 --- a/src/Drivers/Gd/Modifiers/DrawEllipseModifier.php +++ b/src/Drivers/Gd/Modifiers/DrawEllipseModifier.php @@ -2,55 +2,65 @@ namespace Intervention\Image\Drivers\Gd\Modifiers; -use Intervention\Image\Drivers\Abstract\Modifiers\AbstractDrawModifier; -use Intervention\Image\Drivers\Gd\Traits\CanHandleColors; +use Intervention\Image\Drivers\DrawModifier; use Intervention\Image\Interfaces\ImageInterface; -use Intervention\Image\Interfaces\ModifierInterface; -class DrawEllipseModifier extends AbstractDrawModifier implements ModifierInterface +class DrawEllipseModifier extends DrawModifier { - use CanHandleColors; - public function apply(ImageInterface $image): ImageInterface { - return $image->mapFrames(function ($frame) { - if ($this->ellipse()->hasBorder()) { + foreach ($image as $frame) { + if ($this->drawable->hasBorder()) { // slightly smaller ellipse to keep 1px bordered edges clean - if ($this->ellipse()->hasBackgroundColor()) { + if ($this->drawable->hasBackgroundColor()) { imagefilledellipse( - $frame->core(), - $this->position->x(), - $this->position->y(), - $this->ellipse()->getWidth() - 1, - $this->ellipse()->getHeight() - 1, - $this->colorToInteger($this->getBackgroundColor()) + $frame->data(), + $this->position()->x(), + $this->position()->y(), + $this->drawable->width() - 1, + $this->drawable->height() - 1, + $this->driver()->colorToNative( + $this->backgroundColor(), + $image->colorspace() + ) ); } - imagesetthickness($frame->core(), $this->ellipse()->getBorderSize()); + // gd's imageellipse ignores imagesetthickness + // so i use imagearc with 360 degrees instead. + imagesetthickness( + $frame->data(), + $this->drawable->borderSize(), + ); - // gd's imageellipse ignores imagesetthickness so i use - // imagearc with 360 degrees instead. imagearc( - $frame->core(), - $this->position->x(), - $this->position->y(), - $this->ellipse()->getWidth(), - $this->ellipse()->getHeight(), + $frame->data(), + $this->position()->x(), + $this->position()->y(), + $this->drawable->width(), + $this->drawable->height(), 0, 360, - $this->colorToInteger($this->getBorderColor()) + $this->driver()->colorToNative( + $this->borderColor(), + $image->colorspace() + ) ); } else { imagefilledellipse( - $frame->core(), - $this->position->x(), - $this->position->y(), - $this->ellipse()->getWidth(), - $this->ellipse()->getHeight(), - $this->colorToInteger($this->getBackgroundColor()) + $frame->data(), + $this->position()->x(), + $this->position()->y(), + $this->drawable->width(), + $this->drawable->height(), + $this->driver()->colorToNative( + $this->backgroundColor(), + $image->colorspace() + ) ); } - }); + } + + return $image; } } diff --git a/src/Drivers/Gd/Modifiers/DrawLineModifier.php b/src/Drivers/Gd/Modifiers/DrawLineModifier.php index a97157a2..db7e5ae0 100644 --- a/src/Drivers/Gd/Modifiers/DrawLineModifier.php +++ b/src/Drivers/Gd/Modifiers/DrawLineModifier.php @@ -2,26 +2,27 @@ namespace Intervention\Image\Drivers\Gd\Modifiers; -use Intervention\Image\Drivers\Abstract\Modifiers\AbstractDrawModifier; -use Intervention\Image\Drivers\Gd\Traits\CanHandleColors; +use Intervention\Image\Drivers\DrawModifier; use Intervention\Image\Interfaces\ImageInterface; -use Intervention\Image\Interfaces\ModifierInterface; -class DrawLineModifier extends AbstractDrawModifier implements ModifierInterface +class DrawLineModifier extends DrawModifier { - use CanHandleColors; - public function apply(ImageInterface $image): ImageInterface { - return $image->mapFrames(function ($frame) { + foreach ($image as $frame) { imageline( - $frame->core(), - $this->line()->getStart()->x(), - $this->line()->getStart()->y(), - $this->line()->getEnd()->x(), - $this->line()->getEnd()->y(), - $this->colorToInteger($this->getBackgroundColor()) + $frame->data(), + $this->drawable->getStart()->x(), + $this->drawable->getStart()->y(), + $this->drawable->getEnd()->x(), + $this->drawable->getEnd()->y(), + $this->driver()->colorToNative( + $this->backgroundColor(), + $image->colorspace() + ) ); - }); + } + + return $image; } } diff --git a/src/Drivers/Gd/Modifiers/DrawPixelModifier.php b/src/Drivers/Gd/Modifiers/DrawPixelModifier.php index ad3d4563..3802cf3e 100644 --- a/src/Drivers/Gd/Modifiers/DrawPixelModifier.php +++ b/src/Drivers/Gd/Modifiers/DrawPixelModifier.php @@ -2,34 +2,27 @@ namespace Intervention\Image\Drivers\Gd\Modifiers; -use Intervention\Image\Drivers\Gd\Traits\CanHandleColors; -use Intervention\Image\Geometry\Point; +use Intervention\Image\Drivers\DriverModifier; use Intervention\Image\Interfaces\ImageInterface; -use Intervention\Image\Interfaces\ModifierInterface; -use Intervention\Image\Traits\CanHandleInput; -class DrawPixelModifier implements ModifierInterface +class DrawPixelModifier extends DriverModifier { - use CanHandleInput; - use CanHandleColors; - - public function __construct( - protected Point $position, - protected $color - ) { - // - } - public function apply(ImageInterface $image): ImageInterface { - $color = $this->handleInput($this->color); - return $image->mapFrames(function ($frame) use ($color) { + $color = $this->driver()->colorToNative( + $this->driver()->handleInput($this->color), + $image->colorspace() + ); + + foreach ($image as $frame) { imagesetpixel( - $frame->core(), + $frame->data(), $this->position->x(), $this->position->y(), - $this->colorToInteger($color) + $color ); - }); + } + + return $image; } } diff --git a/src/Drivers/Gd/Modifiers/DrawPolygonModifier.php b/src/Drivers/Gd/Modifiers/DrawPolygonModifier.php index f990721e..81eeb202 100644 --- a/src/Drivers/Gd/Modifiers/DrawPolygonModifier.php +++ b/src/Drivers/Gd/Modifiers/DrawPolygonModifier.php @@ -2,42 +2,38 @@ namespace Intervention\Image\Drivers\Gd\Modifiers; -use Intervention\Image\Drivers\Abstract\Modifiers\AbstractDrawModifier; -use Intervention\Image\Drivers\Gd\Traits\CanHandleColors; -use Intervention\Image\Interfaces\DrawableInterface; +use Intervention\Image\Drivers\DrawModifier; use Intervention\Image\Interfaces\ImageInterface; -use Intervention\Image\Interfaces\ModifierInterface; -class DrawPolygonModifier extends AbstractDrawModifier implements ModifierInterface +class DrawPolygonModifier extends DrawModifier { - use CanHandleColors; - - public function __construct( - protected DrawableInterface $drawable - ) { - // - } - public function apply(ImageInterface $image): ImageInterface { - return $image->mapFrames(function ($frame) { - if ($this->polygon()->hasBackgroundColor()) { + foreach ($image as $frame) { + if ($this->drawable->hasBackgroundColor()) { imagefilledpolygon( - $frame->core(), - $this->polygon()->toArray(), - $this->colorToInteger($this->getBackgroundColor()) + $frame->data(), + $this->drawable->toArray(), + $this->driver()->colorToNative( + $this->backgroundColor(), + $image->colorspace() + ) ); } - if ($this->polygon()->hasBorder()) { - imagesetthickness($frame->core(), $this->polygon()->getBorderSize()); + if ($this->drawable->hasBorder()) { + imagesetthickness($frame->data(), $this->drawable->borderSize()); imagepolygon( - $frame->core(), - $this->polygon()->toArray(), - $this->polygon()->count(), - $this->colorToInteger($this->getBorderColor()) + $frame->data(), + $this->drawable->toArray(), + $this->driver()->colorToNative( + $this->borderColor(), + $image->colorspace() + ) ); } - }); + } + + return $image; } } diff --git a/src/Drivers/Gd/Modifiers/DrawRectangleModifier.php b/src/Drivers/Gd/Modifiers/DrawRectangleModifier.php index 7b0322e2..5cb332fd 100644 --- a/src/Drivers/Gd/Modifiers/DrawRectangleModifier.php +++ b/src/Drivers/Gd/Modifiers/DrawRectangleModifier.php @@ -2,43 +2,45 @@ namespace Intervention\Image\Drivers\Gd\Modifiers; -use Intervention\Image\Drivers\Abstract\Modifiers\AbstractDrawModifier; -use Intervention\Image\Drivers\Gd\Traits\CanHandleColors; +use Intervention\Image\Drivers\DrawModifier; use Intervention\Image\Interfaces\ImageInterface; -use Intervention\Image\Interfaces\ModifierInterface; -class DrawRectangleModifier extends AbstractDrawModifier implements ModifierInterface +class DrawRectangleModifier extends DrawModifier { - use CanHandleColors; - public function apply(ImageInterface $image): ImageInterface { - $image->mapFrames(function ($frame) { + foreach ($image as $frame) { // draw background - if ($this->rectangle()->hasBackgroundColor()) { + if ($this->drawable->hasBackgroundColor()) { imagefilledrectangle( - $frame->core(), + $frame->data(), $this->position->x(), $this->position->y(), - $this->position->x() + $this->rectangle()->bottomRightPoint()->x(), - $this->position->y() + $this->rectangle()->bottomRightPoint()->y(), - $this->colorToInteger($this->getBackgroundColor()) + $this->position->x() + $this->drawable->width(), + $this->position->y() + $this->drawable->height(), + $this->driver()->colorToNative( + $this->backgroundColor(), + $image->colorspace() + ) ); } - if ($this->rectangle()->hasBorder()) { - // draw border - imagesetthickness($frame->core(), $this->rectangle()->getBorderSize()); + // draw border + if ($this->drawable->hasBorder()) { + imagesetthickness($frame->data(), $this->drawable->borderSize()); imagerectangle( - $frame->core(), + $frame->data(), $this->position->x(), $this->position->y(), - $this->position->x() + $this->rectangle()->bottomRightPoint()->x(), - $this->position->y() + $this->rectangle()->bottomRightPoint()->y(), - $this->colorToInteger($this->getBorderColor()) + $this->position->x() + $this->drawable->width(), + $this->position->y() + $this->drawable->height(), + $this->driver()->colorToNative( + $this->borderColor(), + $image->colorspace() + ) ); } - }); + } return $image; } diff --git a/src/Drivers/Gd/Modifiers/FillModifier.php b/src/Drivers/Gd/Modifiers/FillModifier.php index fc007a2d..876c8e4b 100644 --- a/src/Drivers/Gd/Modifiers/FillModifier.php +++ b/src/Drivers/Gd/Modifiers/FillModifier.php @@ -2,25 +2,16 @@ namespace Intervention\Image\Drivers\Gd\Modifiers; +use Intervention\Image\Colors\Rgb\Colorspace; +use Intervention\Image\Drivers\DriverModifier; use Intervention\Image\Drivers\Gd\Frame; -use Intervention\Image\Drivers\Gd\Traits\CanHandleColors; -use Intervention\Image\Geometry\Point; -use Intervention\Image\Interfaces\ColorInterface; use Intervention\Image\Interfaces\ImageInterface; -use Intervention\Image\Interfaces\ModifierInterface; -class FillModifier implements ModifierInterface +class FillModifier extends DriverModifier { - use CanHandleColors; - - public function __construct(protected ColorInterface $color, protected ?Point $position = null) - { - // - } - public function apply(ImageInterface $image): ImageInterface { - $color = $this->colorToInteger($this->color); + $color = $this->color(); foreach ($image as $frame) { if ($this->hasPosition()) { @@ -33,21 +24,29 @@ class FillModifier implements ModifierInterface return $image; } - protected function floodFillWithColor(Frame $frame, int $color): void + private function color(): int + { + return $this->driver()->colorToNative( + $this->driver()->handleInput($this->color), + new Colorspace() + ); + } + + private function floodFillWithColor(Frame $frame, int $color): void { imagefill( - $frame->core(), + $frame->data(), $this->position->x(), $this->position->y(), $color ); } - protected function fillAllWithColor(Frame $frame, int $color): void + private function fillAllWithColor(Frame $frame, int $color): void { - imagealphablending($frame->core(), true); + imagealphablending($frame->data(), true); imagefilledrectangle( - $frame->core(), + $frame->data(), 0, 0, $frame->size()->width() - 1, @@ -55,9 +54,4 @@ class FillModifier implements ModifierInterface $color ); } - - protected function hasPosition(): bool - { - return !empty($this->position); - } } diff --git a/src/Drivers/Gd/Modifiers/FitDownModifier.php b/src/Drivers/Gd/Modifiers/FitDownModifier.php index 5bf00774..7662b592 100644 --- a/src/Drivers/Gd/Modifiers/FitDownModifier.php +++ b/src/Drivers/Gd/Modifiers/FitDownModifier.php @@ -6,7 +6,7 @@ use Intervention\Image\Interfaces\SizeInterface; class FitDownModifier extends FitModifier { - protected function getResizeSize(SizeInterface $size): SizeInterface + public function getResizeSize(SizeInterface $size): SizeInterface { return $size->scaleDown($this->width, $this->height); } diff --git a/src/Drivers/Gd/Modifiers/FitModifier.php b/src/Drivers/Gd/Modifiers/FitModifier.php index 7dd567c7..c1842f7b 100644 --- a/src/Drivers/Gd/Modifiers/FitModifier.php +++ b/src/Drivers/Gd/Modifiers/FitModifier.php @@ -2,17 +2,13 @@ namespace Intervention\Image\Drivers\Gd\Modifiers; -use Intervention\Image\Drivers\Abstract\Modifiers\AbstractFitModifier; +use Intervention\Image\Drivers\DriverModifier; use Intervention\Image\Interfaces\FrameInterface; use Intervention\Image\Interfaces\ImageInterface; -use Intervention\Image\Interfaces\ModifierInterface; use Intervention\Image\Interfaces\SizeInterface; -use Intervention\Image\Traits\CanBuildNewImage; -class FitModifier extends AbstractFitModifier implements ModifierInterface +class FitModifier extends DriverModifier { - use CanBuildNewImage; - public function apply(ImageInterface $image): ImageInterface { $crop = $this->getCropSize($image); @@ -28,13 +24,13 @@ class FitModifier extends AbstractFitModifier implements ModifierInterface protected function modifyFrame(FrameInterface $frame, SizeInterface $crop, SizeInterface $resize): void { // create new image - $modified = $this->imageFactory()->newCore( + $modified = $this->driver()->createImage( $resize->width(), $resize->height() - ); + )->core()->native(); // get original image - $original = $frame->core(); + $original = $frame->data(); // preserve transparency $transIndex = imagecolortransparent($original); @@ -61,6 +57,6 @@ class FitModifier extends AbstractFitModifier implements ModifierInterface ); // set new content as resource - $frame->setCore($modified); + $frame->setData($modified); } } diff --git a/src/Drivers/Gd/Modifiers/FlipModifier.php b/src/Drivers/Gd/Modifiers/FlipModifier.php index 9b249ee7..deb82c32 100644 --- a/src/Drivers/Gd/Modifiers/FlipModifier.php +++ b/src/Drivers/Gd/Modifiers/FlipModifier.php @@ -2,15 +2,15 @@ namespace Intervention\Image\Drivers\Gd\Modifiers; +use Intervention\Image\Drivers\DriverModifier; use Intervention\Image\Interfaces\ImageInterface; -use Intervention\Image\Interfaces\ModifierInterface; -class FlipModifier implements ModifierInterface +class FlipModifier extends DriverModifier { public function apply(ImageInterface $image): ImageInterface { foreach ($image as $frame) { - imageflip($frame->core(), IMG_FLIP_VERTICAL); + imageflip($frame->data(), IMG_FLIP_VERTICAL); } return $image; diff --git a/src/Drivers/Gd/Modifiers/FlopModifier.php b/src/Drivers/Gd/Modifiers/FlopModifier.php index b58def62..4eba7f23 100644 --- a/src/Drivers/Gd/Modifiers/FlopModifier.php +++ b/src/Drivers/Gd/Modifiers/FlopModifier.php @@ -2,15 +2,15 @@ namespace Intervention\Image\Drivers\Gd\Modifiers; +use Intervention\Image\Drivers\DriverModifier; use Intervention\Image\Interfaces\ImageInterface; -use Intervention\Image\Interfaces\ModifierInterface; -class FlopModifier implements ModifierInterface +class FlopModifier extends DriverModifier { public function apply(ImageInterface $image): ImageInterface { foreach ($image as $frame) { - imageflip($frame->core(), IMG_FLIP_HORIZONTAL); + imageflip($frame->data(), IMG_FLIP_HORIZONTAL); } return $image; diff --git a/src/Drivers/Gd/Modifiers/GammaModifier.php b/src/Drivers/Gd/Modifiers/GammaModifier.php index 92e76646..111f6f7e 100644 --- a/src/Drivers/Gd/Modifiers/GammaModifier.php +++ b/src/Drivers/Gd/Modifiers/GammaModifier.php @@ -2,20 +2,15 @@ namespace Intervention\Image\Drivers\Gd\Modifiers; +use Intervention\Image\Drivers\DriverModifier; use Intervention\Image\Interfaces\ImageInterface; -use Intervention\Image\Interfaces\ModifierInterface; -class GammaModifier implements ModifierInterface +class GammaModifier extends DriverModifier { - public function __construct(protected float $gamma) - { - // - } - public function apply(ImageInterface $image): ImageInterface { foreach ($image as $frame) { - imagegammacorrect($frame->core(), 1, $this->gamma); + imagegammacorrect($frame->data(), 1, $this->gamma); } return $image; diff --git a/src/Drivers/Gd/Modifiers/GreyscaleModifier.php b/src/Drivers/Gd/Modifiers/GreyscaleModifier.php index 9bf0173e..968ea3f9 100644 --- a/src/Drivers/Gd/Modifiers/GreyscaleModifier.php +++ b/src/Drivers/Gd/Modifiers/GreyscaleModifier.php @@ -2,15 +2,15 @@ namespace Intervention\Image\Drivers\Gd\Modifiers; +use Intervention\Image\Drivers\DriverModifier; use Intervention\Image\Interfaces\ImageInterface; -use Intervention\Image\Interfaces\ModifierInterface; -class GreyscaleModifier implements ModifierInterface +class GreyscaleModifier extends DriverModifier { public function apply(ImageInterface $image): ImageInterface { foreach ($image as $frame) { - imagefilter($frame->core(), IMG_FILTER_GRAYSCALE); + imagefilter($frame->data(), IMG_FILTER_GRAYSCALE); } return $image; diff --git a/src/Drivers/Gd/Modifiers/InvertModifier.php b/src/Drivers/Gd/Modifiers/InvertModifier.php index 41392434..7018e250 100644 --- a/src/Drivers/Gd/Modifiers/InvertModifier.php +++ b/src/Drivers/Gd/Modifiers/InvertModifier.php @@ -2,15 +2,15 @@ namespace Intervention\Image\Drivers\Gd\Modifiers; +use Intervention\Image\Drivers\DriverModifier; use Intervention\Image\Interfaces\ImageInterface; -use Intervention\Image\Interfaces\ModifierInterface; -class InvertModifier implements ModifierInterface +class InvertModifier extends DriverModifier { public function apply(ImageInterface $image): ImageInterface { foreach ($image as $frame) { - imagefilter($frame->core(), IMG_FILTER_NEGATE); + imagefilter($frame->data(), IMG_FILTER_NEGATE); } return $image; diff --git a/src/Drivers/Gd/Modifiers/LimitColorsModifier.php b/src/Drivers/Gd/Modifiers/LimitColorsModifier.php index 84835ef4..709f035b 100644 --- a/src/Drivers/Gd/Modifiers/LimitColorsModifier.php +++ b/src/Drivers/Gd/Modifiers/LimitColorsModifier.php @@ -2,16 +2,11 @@ namespace Intervention\Image\Drivers\Gd\Modifiers; +use Intervention\Image\Drivers\DriverModifier; use Intervention\Image\Interfaces\ImageInterface; -use Intervention\Image\Interfaces\ModifierInterface; -class LimitColorsModifier implements ModifierInterface +class LimitColorsModifier extends DriverModifier { - public function __construct(protected int $limit = 0, protected int $threshold = 256) - { - // - } - public function apply(ImageInterface $image): ImageInterface { // no color limit: no reduction @@ -43,15 +38,15 @@ class LimitColorsModifier implements ModifierInterface imagecolortransparent($reduced, $matte); // copy original image - imagecopy($reduced, $frame->core(), 0, 0, 0, 0, $width, $height); + imagecopy($reduced, $frame->data(), 0, 0, 0, 0, $width, $height); // reduce limit by one to include possible transparency in palette - $limit = imagecolortransparent($frame->core()) === -1 ? $this->limit : $this->limit - 1; + $limit = imagecolortransparent($frame->data()) === -1 ? $this->limit : $this->limit - 1; // decrease colors imagetruecolortopalette($reduced, true, $limit); - $frame->setCore($reduced); + $frame->setData($reduced); } diff --git a/src/Drivers/Gd/Modifiers/PadDownModifier.php b/src/Drivers/Gd/Modifiers/PadDownModifier.php index 897718c8..ce3991aa 100644 --- a/src/Drivers/Gd/Modifiers/PadDownModifier.php +++ b/src/Drivers/Gd/Modifiers/PadDownModifier.php @@ -2,24 +2,6 @@ namespace Intervention\Image\Drivers\Gd\Modifiers; -use Intervention\Image\Geometry\Rectangle; -use Intervention\Image\Interfaces\ImageInterface; -use Intervention\Image\Interfaces\SizeInterface; - class PadDownModifier extends PadModifier { - protected function getCropSize(ImageInterface $image): SizeInterface - { - $resize = $this->getResizeSize($image); - - return $image->size() - ->contain($resize->width(), $resize->height()) - ->alignPivotTo($resize, $this->position); - } - - protected function getResizeSize(ImageInterface $image): SizeInterface - { - return (new Rectangle($this->width, $this->height)) - ->resizeDown($image->width(), $image->height()); - } } diff --git a/src/Drivers/Gd/Modifiers/PadModifier.php b/src/Drivers/Gd/Modifiers/PadModifier.php index f892c889..224f604d 100644 --- a/src/Drivers/Gd/Modifiers/PadModifier.php +++ b/src/Drivers/Gd/Modifiers/PadModifier.php @@ -2,27 +2,20 @@ namespace Intervention\Image\Drivers\Gd\Modifiers; -use Intervention\Image\Drivers\Abstract\Modifiers\AbstractPadModifier; -use Intervention\Image\Drivers\Gd\Traits\CanHandleColors; +use Intervention\Image\Drivers\DriverModifier; use Intervention\Image\Interfaces\ColorInterface; use Intervention\Image\Interfaces\FrameInterface; use Intervention\Image\Interfaces\ImageInterface; -use Intervention\Image\Interfaces\ModifierInterface; use Intervention\Image\Interfaces\SizeInterface; -use Intervention\Image\Traits\CanBuildNewImage; -use Intervention\Image\Traits\CanHandleInput; +use Intervention\Image\Modifiers\FillModifier; -class PadModifier extends AbstractPadModifier implements ModifierInterface +class PadModifier extends DriverModifier { - use CanHandleInput; - use CanHandleColors; - use CanBuildNewImage; - public function apply(ImageInterface $image): ImageInterface { $crop = $this->getCropSize($image); $resize = $this->getResizeSize($image); - $background = $this->handleInput($this->background); + $background = $this->driver()->handleInput($this->background); foreach ($image as $frame) { $this->modify($frame, $crop, $resize, $background); @@ -38,11 +31,12 @@ class PadModifier extends AbstractPadModifier implements ModifierInterface ColorInterface $background ): void { // create new gd image - $modified = $this->imageFactory()->newCore( + $modified = $this->driver()->createImage( $resize->width(), - $resize->height(), - $background - ); + $resize->height() + )->modify( + new FillModifier($background) + )->core()->native(); // make image area transparent to keep transparency // even if background-color is set @@ -62,7 +56,7 @@ class PadModifier extends AbstractPadModifier implements ModifierInterface imagealphablending($modified, true); imagecopyresampled( $modified, - $frame->core(), + $frame->data(), $crop->pivot()->x(), $crop->pivot()->y(), 0, @@ -74,6 +68,6 @@ class PadModifier extends AbstractPadModifier implements ModifierInterface ); // set new content as recource - $frame->setCore($modified); + $frame->setData($modified); } } diff --git a/src/Drivers/Gd/Modifiers/PixelateModifier.php b/src/Drivers/Gd/Modifiers/PixelateModifier.php index 2c3e7547..a4d84901 100644 --- a/src/Drivers/Gd/Modifiers/PixelateModifier.php +++ b/src/Drivers/Gd/Modifiers/PixelateModifier.php @@ -2,21 +2,15 @@ namespace Intervention\Image\Drivers\Gd\Modifiers; -use Intervention\Image\Interfaces\FrameInterface; +use Intervention\Image\Drivers\DriverModifier; use Intervention\Image\Interfaces\ImageInterface; -use Intervention\Image\Interfaces\ModifierInterface; -class PixelateModifier implements ModifierInterface +class PixelateModifier extends DriverModifier { - public function __construct(protected int $size) - { - // - } - public function apply(ImageInterface $image): ImageInterface { foreach ($image as $frame) { - imagefilter($frame->core(), IMG_FILTER_PIXELATE, $this->size, true); + imagefilter($frame->data(), IMG_FILTER_PIXELATE, $this->size, true); } return $image; diff --git a/src/Drivers/Gd/Modifiers/PlaceModifier.php b/src/Drivers/Gd/Modifiers/PlaceModifier.php index d0d1069b..bc370a8a 100644 --- a/src/Drivers/Gd/Modifiers/PlaceModifier.php +++ b/src/Drivers/Gd/Modifiers/PlaceModifier.php @@ -2,38 +2,21 @@ namespace Intervention\Image\Drivers\Gd\Modifiers; +use Intervention\Image\Drivers\DriverModifier; use Intervention\Image\Interfaces\ImageInterface; -use Intervention\Image\Interfaces\ModifierInterface; -use Intervention\Image\Interfaces\PointInterface; -use Intervention\Image\Traits\CanHandleInput; -class PlaceModifier implements ModifierInterface +class PlaceModifier extends DriverModifier { - use CanHandleInput; - - /** - * Create new modifier - * - */ - public function __construct( - protected $element, - protected string $position, - protected int $offset_x, - protected int $offset_y - ) { - // - } - public function apply(ImageInterface $image): ImageInterface { - $watermark = $this->handleInput($this->element); + $watermark = $this->driver()->handleInput($this->element); $position = $this->getPosition($image, $watermark); foreach ($image as $frame) { - imagealphablending($frame->core(), true); + imagealphablending($frame->data(), true); imagecopy( - $frame->core(), - $watermark->frame()->core(), + $frame->data(), + $watermark->core()->native(), $position->x(), $position->y(), 0, @@ -45,12 +28,4 @@ class PlaceModifier implements ModifierInterface return $image; } - - protected function getPosition(ImageInterface $image, ImageInterface $watermark): PointInterface - { - $image_size = $image->size()->movePivot($this->position, $this->offset_x, $this->offset_y); - $watermark_size = $watermark->size()->movePivot($this->position); - - return $image_size->relativePositionTo($watermark_size); - } } diff --git a/src/Drivers/Gd/Modifiers/ProfileModifier.php b/src/Drivers/Gd/Modifiers/ProfileModifier.php new file mode 100644 index 00000000..32c8e129 --- /dev/null +++ b/src/Drivers/Gd/Modifiers/ProfileModifier.php @@ -0,0 +1,17 @@ +failIfNotClass($image, Image::class); - return $image->setFrames(new Collection([ - $this->chosenFrame($image, $this->position) - ])); + return new Image( + $image->driver(), + new Core([ + $this->chosenFrame($image, $this->position) + ]), + $image->exif() + ); } } diff --git a/src/Drivers/Gd/Modifiers/ResizeModifier.php b/src/Drivers/Gd/Modifiers/ResizeModifier.php index e5534eb8..4b1e040a 100644 --- a/src/Drivers/Gd/Modifiers/ResizeModifier.php +++ b/src/Drivers/Gd/Modifiers/ResizeModifier.php @@ -2,22 +2,16 @@ namespace Intervention\Image\Drivers\Gd\Modifiers; +use Intervention\Image\Drivers\DriverModifier; use Intervention\Image\Interfaces\FrameInterface; use Intervention\Image\Interfaces\ImageInterface; -use Intervention\Image\Interfaces\ModifierInterface; use Intervention\Image\Interfaces\SizeInterface; -class ResizeModifier implements ModifierInterface +class ResizeModifier extends DriverModifier { - public function __construct(protected ?int $width = null, protected ?int $height = null) - { - // - } - public function apply(ImageInterface $image): ImageInterface { $resizeTo = $this->getAdjustedSize($image); - foreach ($image as $frame) { $this->resizeFrame($frame, $resizeTo); } @@ -25,12 +19,7 @@ class ResizeModifier implements ModifierInterface return $image; } - protected function getAdjustedSize(ImageInterface $image): SizeInterface - { - return $image->size()->resize($this->width, $this->height); - } - - protected function resizeFrame(FrameInterface $frame, SizeInterface $resizeTo): void + private function resizeFrame(FrameInterface $frame, SizeInterface $resizeTo): void { // create new image $modified = imagecreatetruecolor( @@ -38,8 +27,8 @@ class ResizeModifier implements ModifierInterface $resizeTo->height() ); - // get current image - $current = $frame->core(); + // get current GDImage + $current = $frame->data(); // preserve transparency $transIndex = imagecolortransparent($current); @@ -69,6 +58,11 @@ class ResizeModifier implements ModifierInterface ); // set new content as recource - $frame->setCore($modified); + $frame->setData($modified); + } + + protected function getAdjustedSize(ImageInterface $image): SizeInterface + { + return $image->size()->resize($this->width, $this->height); } } diff --git a/src/Drivers/Gd/Modifiers/ResolutionModifier.php b/src/Drivers/Gd/Modifiers/ResolutionModifier.php index 404e6a2b..9b2e908d 100644 --- a/src/Drivers/Gd/Modifiers/ResolutionModifier.php +++ b/src/Drivers/Gd/Modifiers/ResolutionModifier.php @@ -2,23 +2,18 @@ namespace Intervention\Image\Drivers\Gd\Modifiers; +use Intervention\Image\Drivers\DriverModifier; use Intervention\Image\Interfaces\ImageInterface; -use Intervention\Image\Interfaces\ModifierInterface; -class ResolutionModifier implements ModifierInterface +class ResolutionModifier extends DriverModifier { - public function __construct(protected float $x, protected float $y) - { - // - } - public function apply(ImageInterface $image): ImageInterface { $x = intval(round($this->x)); $y = intval(round($this->y)); foreach ($image as $frame) { - imageresolution($frame->core(), $x, $y); + imageresolution($frame->data(), $x, $y); } return $image; diff --git a/src/Drivers/Gd/Modifiers/RotateModifier.php b/src/Drivers/Gd/Modifiers/RotateModifier.php index 1d9400f5..7f2a680c 100644 --- a/src/Drivers/Gd/Modifiers/RotateModifier.php +++ b/src/Drivers/Gd/Modifiers/RotateModifier.php @@ -5,29 +5,24 @@ namespace Intervention\Image\Drivers\Gd\Modifiers; use Intervention\Image\Colors\Rgb\Channels\Blue; use Intervention\Image\Colors\Rgb\Channels\Green; use Intervention\Image\Colors\Rgb\Channels\Red; -use Intervention\Image\Drivers\Abstract\Modifiers\AbstractRotateModifier; -use Intervention\Image\Drivers\Gd\Traits\CanHandleColors; +use Intervention\Image\Drivers\DriverModifier; use Intervention\Image\Exceptions\RuntimeException; use Intervention\Image\Exceptions\MissingDriverComponentException; use Intervention\Image\Geometry\Rectangle; use Intervention\Image\Interfaces\ColorInterface; use Intervention\Image\Interfaces\FrameInterface; use Intervention\Image\Interfaces\ImageInterface; -use Intervention\Image\Interfaces\ModifierInterface; -use Intervention\Image\Traits\CanBuildNewImage; +use Intervention\Image\Modifiers\FillModifier; use ReflectionException; -class RotateModifier extends AbstractRotateModifier implements ModifierInterface +class RotateModifier extends DriverModifier { - use CanHandleColors; - use CanBuildNewImage; - public function apply(ImageInterface $image): ImageInterface { - $background = $this->handleInput($this->background); + $background = $this->driver()->handleInput($this->background); foreach ($image as $frame) { - $this->modify($frame, $background); + $this->modifyFrame($frame, $background); } return $image; @@ -44,12 +39,12 @@ class RotateModifier extends AbstractRotateModifier implements ModifierInterface * @throws MissingDriverComponentException * @throws ReflectionException */ - protected function modify(FrameInterface $frame, ColorInterface $background): void + protected function modifyFrame(FrameInterface $frame, ColorInterface $background): void { // get transparent color from frame core - $transparent = match ($transparent = imagecolortransparent($frame->core())) { + $transparent = match ($transparent = imagecolortransparent($frame->data())) { -1 => imagecolorallocatealpha( - $frame->core(), + $frame->data(), $background->channel(Red::class)->value(), $background->channel(Green::class)->value(), $background->channel(Blue::class)->value(), @@ -60,7 +55,7 @@ class RotateModifier extends AbstractRotateModifier implements ModifierInterface // rotate original image against transparent background $rotated = imagerotate( - $frame->core(), + $frame->data(), $this->rotationAngle(), $transparent ); @@ -73,19 +68,20 @@ class RotateModifier extends AbstractRotateModifier implements ModifierInterface // create size from original and rotate points $cutout = (new Rectangle( - imagesx($frame->core()), - imagesy($frame->core()), + imagesx($frame->data()), + imagesy($frame->data()), $container->pivot() ))->align('center') ->valign('center') ->rotate($this->rotationAngle() * -1); - // create new gd core - $modified = $this->imageFactory()->newCore( + // create new gd image + $modified = $this->driver()->createImage( imagesx($rotated), - imagesy($rotated), - $background - ); + imagesy($rotated) + )->modify(new FillModifier($background)) + ->core() + ->native(); // draw the cutout on new gd image to have a transparent // background where the rotated image will be placed @@ -109,6 +105,6 @@ class RotateModifier extends AbstractRotateModifier implements ModifierInterface imagesy($rotated) ); - $frame->setCore($modified); + $frame->setData($modified); } } diff --git a/src/Drivers/Gd/Modifiers/SharpenModifier.php b/src/Drivers/Gd/Modifiers/SharpenModifier.php index 00a812cd..5fef4955 100644 --- a/src/Drivers/Gd/Modifiers/SharpenModifier.php +++ b/src/Drivers/Gd/Modifiers/SharpenModifier.php @@ -2,27 +2,22 @@ namespace Intervention\Image\Drivers\Gd\Modifiers; +use Intervention\Image\Drivers\DriverModifier; use Intervention\Image\Interfaces\ImageInterface; -use Intervention\Image\Interfaces\ModifierInterface; -class SharpenModifier implements ModifierInterface +class SharpenModifier extends DriverModifier { - public function __construct(protected int $amount) - { - // - } - public function apply(ImageInterface $image): ImageInterface { $matrix = $this->matrix(); foreach ($image as $frame) { - imageconvolution($frame->core(), $matrix, 1, 0); + imageconvolution($frame->data(), $matrix, 1, 0); } return $image; } - protected function matrix(): array + private function matrix(): array { $min = $this->amount >= 10 ? $this->amount * -0.01 : 0; $max = $this->amount * -0.025; diff --git a/src/Drivers/Gd/Modifiers/TextWriter.php b/src/Drivers/Gd/Modifiers/TextWriter.php index 37546755..fe20edfc 100644 --- a/src/Drivers/Gd/Modifiers/TextWriter.php +++ b/src/Drivers/Gd/Modifiers/TextWriter.php @@ -2,26 +2,25 @@ namespace Intervention\Image\Drivers\Gd\Modifiers; -use Intervention\Image\Drivers\Abstract\AbstractTextWriter; -use Intervention\Image\Drivers\Gd\Font; +use Intervention\Image\Drivers\DriverModifier; use Intervention\Image\Drivers\Gd\Traits\CanHandleColors; use Intervention\Image\Interfaces\ImageInterface; -class TextWriter extends AbstractTextWriter +class TextWriter extends DriverModifier { use CanHandleColors; public function apply(ImageInterface $image): ImageInterface { $lines = $this->getAlignedTextBlock(); - $font = $this->failIfNotClass($this->getFont(), Font::class); + $font = $this->font; $color = $this->colorToInteger($font->getColor()); foreach ($image as $frame) { if ($this->font->hasFilename()) { foreach ($lines as $line) { imagettftext( - $frame->core(), + $frame->data(), $font->getSize(), $font->getAngle() * (-1), $line->getPosition()->x(), @@ -34,7 +33,7 @@ class TextWriter extends AbstractTextWriter } else { foreach ($lines as $line) { imagestring( - $frame->core(), + $frame->data(), $font->getGdFont(), $line->getPosition()->x(), $line->getPosition()->y(), diff --git a/src/Drivers/Gd/Traits/CanHandleColors.php b/src/Drivers/Gd/Traits/CanHandleColors.php index 66ac4a2e..3159f6ec 100644 --- a/src/Drivers/Gd/Traits/CanHandleColors.php +++ b/src/Drivers/Gd/Traits/CanHandleColors.php @@ -10,7 +10,7 @@ use Intervention\Image\Colors\Rgb\Channels\Blue; use Intervention\Image\Colors\Rgb\Channels\Green; use Intervention\Image\Colors\Rgb\Channels\Red; -trait CanHandleColors +trait DELETE___CanHandleColors { /** * Allocate given color in given gd image and return color value/index diff --git a/src/Drivers/Imagick/ColorProcessor.php b/src/Drivers/Imagick/ColorProcessor.php new file mode 100644 index 00000000..c92c6842 --- /dev/null +++ b/src/Drivers/Imagick/ColorProcessor.php @@ -0,0 +1,22 @@ +convertTo($this->colorspace) + ); + } +} diff --git a/src/Drivers/Imagick/Core.php b/src/Drivers/Imagick/Core.php new file mode 100644 index 00000000..264d74d8 --- /dev/null +++ b/src/Drivers/Imagick/Core.php @@ -0,0 +1,107 @@ +imagick->getNumberImages(); + } + + public function current(): mixed + { + $this->imagick->setIteratorIndex($this->iteratorIndex); + + return new Frame($this->imagick->current()); + } + + public function next(): void + { + $this->iteratorIndex = $this->iteratorIndex + 1; + } + + public function key(): mixed + { + return $this->iteratorIndex; + } + + public function valid(): bool + { + try { + $result = $this->imagick->setIteratorIndex($this->iteratorIndex); + } catch (ImagickException $e) { + return false; + } + + return $result; + } + + public function rewind(): void + { + $this->iteratorIndex = 0; + } + + public function native() + { + return $this->imagick; + } + + public function width(): int + { + return $this->imagick->getImageWidth(); + } + + public function height(): int + { + return $this->imagick->getImageHeight(); + } + + public function frame(int $position): FrameInterface + { + foreach ($this->imagick as $core) { + if ($core->getIteratorIndex() == $position) { + return new Frame($core); + } + } + + throw new AnimationException('Frame #' . $position . ' is not be found in the image.'); + } + + public function loops(): int + { + return $this->imagick->getImageIterations(); + } + + public function setLoops(int $loops): CoreInterface + { + $this->imagick = $this->imagick->coalesceImages(); + $this->imagick->setImageIterations($loops); + + return $this; + } + + public function colorspace(): ColorspaceInterface + { + return match ($this->imagick->getImageColorspace()) { + Imagick::COLORSPACE_CMYK => new CmykColorspace(), + default => new RgbColorspace(), + }; + } +} diff --git a/src/Drivers/Imagick/Decoders/BinaryImageDecoder.php b/src/Drivers/Imagick/Decoders/BinaryImageDecoder.php index f8b7349a..42356a60 100644 --- a/src/Drivers/Imagick/Decoders/BinaryImageDecoder.php +++ b/src/Drivers/Imagick/Decoders/BinaryImageDecoder.php @@ -4,9 +4,11 @@ namespace Intervention\Image\Drivers\Imagick\Decoders; use Imagick; use ImagickException; -use Intervention\Image\Drivers\Abstract\Decoders\AbstractDecoder; -use Intervention\Image\Drivers\Imagick\Image; +use Intervention\Image\Drivers\AbstractDecoder; +use Intervention\Image\Drivers\Imagick\Core; +use Intervention\Image\Drivers\Imagick\Driver; use Intervention\Image\Exceptions\DecoderException; +use Intervention\Image\Image; use Intervention\Image\Interfaces\ColorInterface; use Intervention\Image\Interfaces\DecoderInterface; use Intervention\Image\Interfaces\ImageInterface; @@ -46,9 +48,11 @@ class BinaryImageDecoder extends AbstractDecoder implements DecoderInterface // set new orientation in image $imagick->setImageOrientation(Imagick::ORIENTATION_TOPLEFT); - $image = new Image($imagick); - $image->setLoops($imagick->getImageIterations()); - $image->setExif($this->decodeExifData($input)); + $image = new Image( + new Driver(), + new Core($imagick), + $this->decodeExifData($input) + ); return $image; } diff --git a/src/Drivers/Imagick/Decoders/ColorObjectDecoder.php b/src/Drivers/Imagick/Decoders/ColorObjectDecoder.php index 426d2e52..099c7766 100644 --- a/src/Drivers/Imagick/Decoders/ColorObjectDecoder.php +++ b/src/Drivers/Imagick/Decoders/ColorObjectDecoder.php @@ -2,7 +2,7 @@ namespace Intervention\Image\Drivers\Imagick\Decoders; -use Intervention\Image\Drivers\Abstract\Decoders\AbstractDecoder; +use Intervention\Image\Drivers\AbstractDecoder; use Intervention\Image\Exceptions\DecoderException; use Intervention\Image\Interfaces\ColorInterface; use Intervention\Image\Interfaces\DecoderInterface; diff --git a/src/Drivers/Imagick/Decoders/ImageObjectDecoder.php b/src/Drivers/Imagick/Decoders/ImageObjectDecoder.php index 9f72634f..da476168 100644 --- a/src/Drivers/Imagick/Decoders/ImageObjectDecoder.php +++ b/src/Drivers/Imagick/Decoders/ImageObjectDecoder.php @@ -2,7 +2,7 @@ namespace Intervention\Image\Drivers\Imagick\Decoders; -use Intervention\Image\Drivers\Abstract\Decoders\AbstractDecoder; +use Intervention\Image\Drivers\AbstractDecoder; use Intervention\Image\Exceptions\DecoderException; use Intervention\Image\Interfaces\ColorInterface; use Intervention\Image\Interfaces\DecoderInterface; diff --git a/src/Drivers/Imagick/Driver.php b/src/Drivers/Imagick/Driver.php new file mode 100644 index 00000000..e1d46ee7 --- /dev/null +++ b/src/Drivers/Imagick/Driver.php @@ -0,0 +1,38 @@ +newImage($width, $height, $background, 'png'); + $imagick->setType(Imagick::IMGTYPE_UNDEFINED); + $imagick->setImageType(Imagick::IMGTYPE_UNDEFINED); + $imagick->setColorspace(Imagick::COLORSPACE_SRGB); + $imagick->setImageResolution(96, 96); + + return new Image($this, new Core($imagick)); + } + + public function handleInput(mixed $input): ImageInterface|ColorInterface + { + return (new InputHandler())->handle($input); + } + + public function colorToNative(ColorInterface $color, ColorspaceInterface $colorspace): mixed + { + return (new ColorProcessor($colorspace))->colorToNative($color); + } +} diff --git a/src/Drivers/Imagick/Encoders/AvifEncoder.php b/src/Drivers/Imagick/Encoders/AvifEncoder.php index 0c5c7c0d..f3e6bf05 100644 --- a/src/Drivers/Imagick/Encoders/AvifEncoder.php +++ b/src/Drivers/Imagick/Encoders/AvifEncoder.php @@ -3,24 +3,18 @@ namespace Intervention\Image\Drivers\Imagick\Encoders; use Imagick; -use Intervention\Image\Drivers\Abstract\Encoders\AbstractEncoder; +use Intervention\Image\Drivers\DriverEncoder; use Intervention\Image\EncodedImage; -use Intervention\Image\Interfaces\EncoderInterface; use Intervention\Image\Interfaces\ImageInterface; -class AvifEncoder extends AbstractEncoder implements EncoderInterface +class AvifEncoder extends DriverEncoder { - public function __construct(int $quality) - { - $this->quality = $quality; - } - public function encode(ImageInterface $image): EncodedImage { $format = 'AVIF'; $compression = Imagick::COMPRESSION_ZIP; - $imagick = $image->frame()->core(); + $imagick = $image->core()->native(); $imagick->setFormat($format); $imagick->setImageFormat($format); $imagick->setCompression($compression); diff --git a/src/Drivers/Imagick/Encoders/BmpEncoder.php b/src/Drivers/Imagick/Encoders/BmpEncoder.php index ad07bdc9..871cd833 100644 --- a/src/Drivers/Imagick/Encoders/BmpEncoder.php +++ b/src/Drivers/Imagick/Encoders/BmpEncoder.php @@ -3,26 +3,20 @@ namespace Intervention\Image\Drivers\Imagick\Encoders; use Imagick; -use Intervention\Image\Drivers\Abstract\Encoders\AbstractEncoder; -use Intervention\Image\Drivers\Imagick\Modifiers\LimitColorsModifier; +use Intervention\Image\Drivers\DriverEncoder; +use Intervention\Image\Modifiers\LimitColorsModifier; use Intervention\Image\EncodedImage; -use Intervention\Image\Interfaces\EncoderInterface; use Intervention\Image\Interfaces\ImageInterface; -class BmpEncoder extends AbstractEncoder implements EncoderInterface +class BmpEncoder extends DriverEncoder { - public function __construct(protected int $color_limit = 0) - { - // - } - public function encode(ImageInterface $image): EncodedImage { $format = 'bmp'; $compression = Imagick::COMPRESSION_NO; $image = $image->modify(new LimitColorsModifier($this->color_limit)); - $imagick = $image->frame()->core(); + $imagick = $image->core()->native(); $imagick->setFormat($format); $imagick->setImageFormat($format); $imagick->setCompression($compression); diff --git a/src/Drivers/Imagick/Encoders/GifEncoder.php b/src/Drivers/Imagick/Encoders/GifEncoder.php index 68ac619f..ab1696cc 100644 --- a/src/Drivers/Imagick/Encoders/GifEncoder.php +++ b/src/Drivers/Imagick/Encoders/GifEncoder.php @@ -3,37 +3,23 @@ namespace Intervention\Image\Drivers\Imagick\Encoders; use Imagick; -use Intervention\Image\Drivers\Abstract\Encoders\AbstractEncoder; -use Intervention\Image\Drivers\Imagick\Image; -use Intervention\Image\Drivers\Imagick\Modifiers\LimitColorsModifier; +use Intervention\Image\Drivers\DriverEncoder; +use Intervention\Image\Modifiers\LimitColorsModifier; use Intervention\Image\EncodedImage; -use Intervention\Image\Exceptions\EncoderException; -use Intervention\Image\Interfaces\EncoderInterface; use Intervention\Image\Interfaces\ImageInterface; -use Intervention\Image\Traits\CanCheckType; -class GifEncoder extends AbstractEncoder implements EncoderInterface +class GifEncoder extends DriverEncoder { - use CanCheckType; - - public function __construct(protected int $color_limit = 0) - { - // - } - public function encode(ImageInterface $image): EncodedImage { + $image = $image->modify(new LimitColorsModifier($this->color_limit)); + + $format = 'gif'; $compression = Imagick::COMPRESSION_LZW; - if (!is_a($image, Image::class)) { - throw new EncoderException('Image does not match the current driver.'); - } + $imagick = $image->core()->native(); - $image = $this->failIfNotClass($image, Image::class); - - $image = $image->modify(new LimitColorsModifier($this->color_limit)); - $imagick = $image->getImagick(); $imagick->setFormat($format); $imagick->setImageFormat($format); $imagick->setCompression($compression); diff --git a/src/Drivers/Imagick/Encoders/JpegEncoder.php b/src/Drivers/Imagick/Encoders/JpegEncoder.php index 7345b27d..f62afcf8 100644 --- a/src/Drivers/Imagick/Encoders/JpegEncoder.php +++ b/src/Drivers/Imagick/Encoders/JpegEncoder.php @@ -3,24 +3,18 @@ namespace Intervention\Image\Drivers\Imagick\Encoders; use Imagick; -use Intervention\Image\Drivers\Abstract\Encoders\AbstractEncoder; +use Intervention\Image\Drivers\DriverEncoder; use Intervention\Image\EncodedImage; -use Intervention\Image\Interfaces\EncoderInterface; use Intervention\Image\Interfaces\ImageInterface; -class JpegEncoder extends AbstractEncoder implements EncoderInterface +class JpegEncoder extends DriverEncoder { - public function __construct(int $quality) - { - $this->quality = $quality; - } - public function encode(ImageInterface $image): EncodedImage { $format = 'jpeg'; $compression = Imagick::COMPRESSION_JPEG; - $imagick = $image->frame()->core(); + $imagick = $image->core()->native(); $imagick->setImageBackgroundColor('white'); $imagick->setBackgroundColor('white'); $imagick->setFormat($format); diff --git a/src/Drivers/Imagick/Encoders/PngEncoder.php b/src/Drivers/Imagick/Encoders/PngEncoder.php index 4c31ca8b..69679adf 100644 --- a/src/Drivers/Imagick/Encoders/PngEncoder.php +++ b/src/Drivers/Imagick/Encoders/PngEncoder.php @@ -3,26 +3,20 @@ namespace Intervention\Image\Drivers\Imagick\Encoders; use Imagick; -use Intervention\Image\Drivers\Abstract\Encoders\AbstractEncoder; -use Intervention\Image\Drivers\Imagick\Modifiers\LimitColorsModifier; +use Intervention\Image\Drivers\DriverEncoder; +use Intervention\Image\Modifiers\LimitColorsModifier; use Intervention\Image\EncodedImage; -use Intervention\Image\Interfaces\EncoderInterface; use Intervention\Image\Interfaces\ImageInterface; -class PngEncoder extends AbstractEncoder implements EncoderInterface +class PngEncoder extends DriverEncoder { - public function __construct(protected int $color_limit = 0) - { - // - } - public function encode(ImageInterface $image): EncodedImage { $format = 'png'; $compression = Imagick::COMPRESSION_ZIP; $image = $image->modify(new LimitColorsModifier($this->color_limit)); - $imagick = $image->frame()->core(); + $imagick = $image->core()->frame()->data(); $imagick->setFormat($format); $imagick->setImageFormat($format); $imagick->setCompression($compression); diff --git a/src/Drivers/Imagick/Encoders/WebpEncoder.php b/src/Drivers/Imagick/Encoders/WebpEncoder.php index 5965c20a..df7f65e1 100644 --- a/src/Drivers/Imagick/Encoders/WebpEncoder.php +++ b/src/Drivers/Imagick/Encoders/WebpEncoder.php @@ -4,24 +4,18 @@ namespace Intervention\Image\Drivers\Imagick\Encoders; use Imagick; use ImagickPixel; -use Intervention\Image\Drivers\Abstract\Encoders\AbstractEncoder; +use Intervention\Image\Drivers\DriverEncoder; use Intervention\Image\EncodedImage; -use Intervention\Image\Interfaces\EncoderInterface; use Intervention\Image\Interfaces\ImageInterface; -class WebpEncoder extends AbstractEncoder implements EncoderInterface +class WebpEncoder extends DriverEncoder { - public function __construct(int $quality) - { - $this->quality = $quality; - } - public function encode(ImageInterface $image): EncodedImage { $format = 'webp'; $compression = Imagick::COMPRESSION_ZIP; - $imagick = $image->frame()->core(); + $imagick = $image->core()->native(); $imagick->setImageBackgroundColor(new ImagickPixel('transparent')); $imagick = $imagick->mergeImageLayers(Imagick::LAYERMETHOD_MERGE); diff --git a/src/Drivers/Imagick/Factory.php b/src/Drivers/Imagick/Factory.php index bb441623..2f5d777d 100644 --- a/src/Drivers/Imagick/Factory.php +++ b/src/Drivers/Imagick/Factory.php @@ -13,7 +13,7 @@ use Intervention\Image\Interfaces\ImageInterface; use Intervention\Image\Traits\CanCheckType; use Intervention\Image\Traits\CanHandleInput; -class Factory implements FactoryInterface +class DELETE___FactoryFactory implements FactoryInterface { use CanHandleInput; use CanCheckType; diff --git a/src/Drivers/Imagick/Font.php b/src/Drivers/Imagick/Font.php index a7d7c2e4..743f60fe 100644 --- a/src/Drivers/Imagick/Font.php +++ b/src/Drivers/Imagick/Font.php @@ -4,7 +4,7 @@ namespace Intervention\Image\Drivers\Imagick; use Imagick; use ImagickDraw; -use Intervention\Image\Drivers\Abstract\AbstractFont; +use Intervention\Image\Drivers\AbstractFont; use Intervention\Image\Drivers\Imagick\Traits\CanHandleColors; use Intervention\Image\Exceptions\FontException; use Intervention\Image\Geometry\Polygon; diff --git a/src/Drivers/Imagick/Frame.php b/src/Drivers/Imagick/Frame.php index 6f674d9f..963c67ee 100644 --- a/src/Drivers/Imagick/Frame.php +++ b/src/Drivers/Imagick/Frame.php @@ -4,66 +4,72 @@ namespace Intervention\Image\Drivers\Imagick; use Imagick; use Intervention\Image\Geometry\Rectangle; +use Intervention\Image\Image; +use Intervention\Image\Interfaces\DriverInterface; use Intervention\Image\Interfaces\FrameInterface; use Intervention\Image\Interfaces\ImageInterface; use Intervention\Image\Interfaces\SizeInterface; class Frame implements FrameInterface { - public function __construct(protected Imagick $core) + public function __construct(protected Imagick $data) { - // } - public function setCore($core): FrameInterface + public function toImage(DriverInterface $driver): ImageInterface { - $this->core = $core; + return new Image($driver, new Core($this->data())); + } + + public function setData($data): FrameInterface + { + $this->data = $data; return $this; } - public function core(): Imagick + public function data(): Imagick { - return $this->core; + return $this->data; } public function size(): SizeInterface { return new Rectangle( - $this->core->getImageWidth(), - $this->core->getImageHeight() + $this->data->getImageWidth(), + $this->data->getImageHeight() ); } public function delay(): float { - return $this->core->getImageDelay() / 100; + return $this->data->getImageDelay() / 100; } public function setDelay(float $delay): FrameInterface { - $this->core->setImageDelay(intval(round($delay * 100))); + $this->data->setImageDelay(intval(round($delay * 100))); return $this; } public function dispose(): int { - return $this->core->getImageDispose(); + return $this->data->getImageDispose(); } public function setDispose(int $dispose): FrameInterface { - $this->core->setImageDispose($dispose); + $this->data->setImageDispose($dispose); return $this; } public function setOffset(int $left, int $top): FrameInterface { - $this->core->setImagePage( - $this->core->getImageWidth(), - $this->core->getImageHeight(), + $this->data->setImagePage( + $this->data->getImageWidth(), + $this->data->getImageHeight(), $left, $top ); @@ -73,7 +79,7 @@ class Frame implements FrameInterface public function offsetLeft(): int { - return $this->core->getImagePage()['x']; + return $this->data->getImagePage()['x']; } public function setOffsetLeft(int $offset): FrameInterface @@ -83,16 +89,11 @@ class Frame implements FrameInterface public function offsetTop(): int { - return $this->core->getImagePage()['y']; + return $this->data->getImagePage()['y']; } public function setOffsetTop(int $offset): FrameInterface { return $this->setOffset($this->offsetLeft(), $offset); } - - public function toImage(): ImageInterface - { - return new Image($this->core()); - } } diff --git a/src/Drivers/Imagick/Image.php b/src/Drivers/Imagick/Image.php index 4ae52f57..7a91161a 100644 --- a/src/Drivers/Imagick/Image.php +++ b/src/Drivers/Imagick/Image.php @@ -23,7 +23,7 @@ use Intervention\Image\Interfaces\ResolutionInterface; use Intervention\Image\Resolution; use Iterator; -class Image extends AbstractImage implements ImageInterface, Iterator +class DELETE__Image extends AbstractImage implements ImageInterface, Iterator { use CanHandleColors; diff --git a/src/Drivers/Imagick/InputHandler.php b/src/Drivers/Imagick/InputHandler.php index a7bcb6f5..b03d079a 100644 --- a/src/Drivers/Imagick/InputHandler.php +++ b/src/Drivers/Imagick/InputHandler.php @@ -7,7 +7,7 @@ use Intervention\Image\Colors\Rgb\Decoders\StringColorDecoder as RgbStringColorD use Intervention\Image\Colors\Rgb\Decoders\HtmlColornameDecoder; use Intervention\Image\Colors\Rgb\Decoders\TransparentColorDecoder; use Intervention\Image\Colors\Cmyk\Decoders\StringColorDecoder as CmykStringColorDecoder; -use Intervention\Image\Drivers\Abstract\AbstractInputHandler; +use Intervention\Image\Drivers\AbstractInputHandler; use Intervention\Image\Drivers\Imagick\Decoders\ImageObjectDecoder; use Intervention\Image\Drivers\Imagick\Decoders\ColorObjectDecoder; use Intervention\Image\Drivers\Imagick\Decoders\FilePointerImageDecoder; diff --git a/src/Drivers/Imagick/Modifiers/BlurModifier.php b/src/Drivers/Imagick/Modifiers/BlurModifier.php index e15192f0..8470cc26 100644 --- a/src/Drivers/Imagick/Modifiers/BlurModifier.php +++ b/src/Drivers/Imagick/Modifiers/BlurModifier.php @@ -2,20 +2,15 @@ namespace Intervention\Image\Drivers\Imagick\Modifiers; +use Intervention\Image\Drivers\DriverModifier; use Intervention\Image\Interfaces\ImageInterface; -use Intervention\Image\Interfaces\ModifierInterface; -class BlurModifier implements ModifierInterface +class BlurModifier extends DriverModifier { - public function __construct(protected int $amount) - { - // - } - public function apply(ImageInterface $image): ImageInterface { foreach ($image as $frame) { - $frame->core()->blurImage(1 * $this->amount, 0.5 * $this->amount); + $frame->data()->blurImage(1 * $this->amount, 0.5 * $this->amount); } return $image; diff --git a/src/Drivers/Imagick/Modifiers/BrightnessModifier.php b/src/Drivers/Imagick/Modifiers/BrightnessModifier.php index a68180eb..c4f10229 100644 --- a/src/Drivers/Imagick/Modifiers/BrightnessModifier.php +++ b/src/Drivers/Imagick/Modifiers/BrightnessModifier.php @@ -2,20 +2,15 @@ namespace Intervention\Image\Drivers\Imagick\Modifiers; +use Intervention\Image\Drivers\DriverModifier; use Intervention\Image\Interfaces\ImageInterface; -use Intervention\Image\Interfaces\ModifierInterface; -class BrightnessModifier implements ModifierInterface +class BrightnessModifier extends DriverModifier { - public function __construct(protected int $level) - { - // - } - public function apply(ImageInterface $image): ImageInterface { foreach ($image as $frame) { - $frame->core()->modulateImage(100 + $this->level, 100, 100); + $frame->data()->modulateImage(100 + $this->level, 100, 100); } return $image; diff --git a/src/Drivers/Imagick/Modifiers/ColorizeModifier.php b/src/Drivers/Imagick/Modifiers/ColorizeModifier.php index 3798ee06..729ef576 100644 --- a/src/Drivers/Imagick/Modifiers/ColorizeModifier.php +++ b/src/Drivers/Imagick/Modifiers/ColorizeModifier.php @@ -3,31 +3,22 @@ namespace Intervention\Image\Drivers\Imagick\Modifiers; use Imagick; +use Intervention\Image\Drivers\DriverModifier; use Intervention\Image\Interfaces\ImageInterface; -use Intervention\Image\Interfaces\ModifierInterface; -class ColorizeModifier implements ModifierInterface +class ColorizeModifier extends DriverModifier { - public function __construct( - protected int $red = 0, - protected int $green = 0, - protected int $blue = 0 - ) { - // - } - public function apply(ImageInterface $image): ImageInterface { - // normalize colorize levels $red = $this->normalizeLevel($this->red); $green = $this->normalizeLevel($this->green); $blue = $this->normalizeLevel($this->blue); foreach ($image as $frame) { - $qrange = $frame->core()->getQuantumRange(); - $frame->core()->levelImage(0, $red, $qrange['quantumRangeLong'], Imagick::CHANNEL_RED); - $frame->core()->levelImage(0, $green, $qrange['quantumRangeLong'], Imagick::CHANNEL_GREEN); - $frame->core()->levelImage(0, $blue, $qrange['quantumRangeLong'], Imagick::CHANNEL_BLUE); + $qrange = $frame->data()->getQuantumRange(); + $frame->data()->levelImage(0, $red, $qrange['quantumRangeLong'], Imagick::CHANNEL_RED); + $frame->data()->levelImage(0, $green, $qrange['quantumRangeLong'], Imagick::CHANNEL_GREEN); + $frame->data()->levelImage(0, $blue, $qrange['quantumRangeLong'], Imagick::CHANNEL_BLUE); } return $image; diff --git a/src/Drivers/Imagick/Modifiers/ColorspaceModifier.php b/src/Drivers/Imagick/Modifiers/ColorspaceModifier.php index f9ef2f0d..2821ba36 100644 --- a/src/Drivers/Imagick/Modifiers/ColorspaceModifier.php +++ b/src/Drivers/Imagick/Modifiers/ColorspaceModifier.php @@ -3,34 +3,23 @@ namespace Intervention\Image\Drivers\Imagick\Modifiers; use Imagick; -use Intervention\Image\Colors\Cmyk\Colorspace as CmykColorspace; -use Intervention\Image\Colors\Rgb\Colorspace as RgbColorspace; -use Intervention\Image\Drivers\Imagick\Image; +use Intervention\Image\Drivers\DriverModifier; use Intervention\Image\Exceptions\NotSupportedException; use Intervention\Image\Interfaces\ColorspaceInterface; use Intervention\Image\Interfaces\ImageInterface; -use Intervention\Image\Interfaces\ModifierInterface; -use Intervention\Image\Traits\CanCheckType; -class ColorspaceModifier implements ModifierInterface +class ColorspaceModifier extends DriverModifier { - use CanCheckType; - protected static $mapping = [ RgbColorspace::class => Imagick::COLORSPACE_SRGB, CmykColorspace::class => Imagick::COLORSPACE_CMYK, ]; - public function __construct(protected string|ColorspaceInterface $target) - { - // - } - public function apply(ImageInterface $image): ImageInterface { $colorspace = $this->targetColorspace(); - $imagick = $this->failIfNotClass($image, Image::class)->getImagick(); + $imagick = $image->core()->native(); $imagick->transformImageColorspace( $this->getImagickColorspace($colorspace) ); @@ -46,21 +35,4 @@ class ColorspaceModifier implements ModifierInterface return self::$mapping[get_class($colorspace)]; } - - private function targetColorspace(): ColorspaceInterface - { - if (is_object($this->target)) { - return $this->target; - } - - if (in_array($this->target, ['rgb', 'RGB', RgbColorspace::class])) { - return new RgbColorspace(); - } - - if (in_array($this->target, ['cmyk', 'CMYK', CmykColorspace::class])) { - return new CmykColorspace(); - } - - throw new NotSupportedException('Given colorspace is not supported.'); - } } diff --git a/src/Drivers/Imagick/Modifiers/ContrastModifier.php b/src/Drivers/Imagick/Modifiers/ContrastModifier.php index abad6e09..cb9e8542 100644 --- a/src/Drivers/Imagick/Modifiers/ContrastModifier.php +++ b/src/Drivers/Imagick/Modifiers/ContrastModifier.php @@ -2,20 +2,15 @@ namespace Intervention\Image\Drivers\Imagick\Modifiers; +use Intervention\Image\Drivers\DriverModifier; use Intervention\Image\Interfaces\ImageInterface; -use Intervention\Image\Interfaces\ModifierInterface; -class ContrastModifier implements ModifierInterface +class ContrastModifier extends DriverModifier { - public function __construct(protected int $level) - { - // - } - public function apply(ImageInterface $image): ImageInterface { foreach ($image as $frame) { - $frame->core()->sigmoidalContrastImage($this->level > 0, abs($this->level / 4), 0); + $frame->data()->sigmoidalContrastImage($this->level > 0, abs($this->level / 4), 0); } return $image; diff --git a/src/Drivers/Imagick/Modifiers/CropModifier.php b/src/Drivers/Imagick/Modifiers/CropModifier.php index 274857b6..3931d073 100644 --- a/src/Drivers/Imagick/Modifiers/CropModifier.php +++ b/src/Drivers/Imagick/Modifiers/CropModifier.php @@ -2,30 +2,17 @@ namespace Intervention\Image\Drivers\Imagick\Modifiers; -use Intervention\Image\Geometry\Rectangle; +use Intervention\Image\Drivers\DriverModifier; use Intervention\Image\Interfaces\ImageInterface; -use Intervention\Image\Interfaces\ModifierInterface; -class CropModifier implements ModifierInterface +class CropModifier extends DriverModifier { - public function __construct( - protected int $width, - protected int $height, - protected int $offset_x = 0, - protected int $offset_y = 0, - protected string $position = 'top-left' - ) { - // - } - public function apply(ImageInterface $image): ImageInterface { - $crop = new Rectangle($this->width, $this->height); - $crop->align($this->position); - $crop->alignPivotTo($image->size(), $this->position); + $crop = $this->crop($image); foreach ($image as $frame) { - $frame->core()->extentImage( + $frame->data()->extentImage( $crop->width(), $crop->height(), $crop->pivot()->x() + $this->offset_x, diff --git a/src/Drivers/Imagick/Modifiers/DestroyModifier.php b/src/Drivers/Imagick/Modifiers/DestroyModifier.php deleted file mode 100644 index 6140a479..00000000 --- a/src/Drivers/Imagick/Modifiers/DestroyModifier.php +++ /dev/null @@ -1,18 +0,0 @@ -core()->clear(); - } - - return $image; - } -} diff --git a/src/Drivers/Imagick/Modifiers/DrawEllipseModifier.php b/src/Drivers/Imagick/Modifiers/DrawEllipseModifier.php index 78d56e10..57166f3e 100644 --- a/src/Drivers/Imagick/Modifiers/DrawEllipseModifier.php +++ b/src/Drivers/Imagick/Modifiers/DrawEllipseModifier.php @@ -3,40 +3,44 @@ namespace Intervention\Image\Drivers\Imagick\Modifiers; use ImagickDraw; -use Intervention\Image\Drivers\Abstract\Modifiers\AbstractDrawModifier; -use Intervention\Image\Drivers\Imagick\Traits\CanHandleColors; +use Intervention\Image\Drivers\DrawModifier; use Intervention\Image\Interfaces\ImageInterface; -use Intervention\Image\Interfaces\ModifierInterface; -class DrawEllipseModifier extends AbstractDrawModifier implements ModifierInterface +class DrawEllipseModifier extends DrawModifier { - use CanHandleColors; - public function apply(ImageInterface $image): ImageInterface { - $colorspace = $image->colorspace(); - $background_color = $this->colorToPixel($this->getBackgroundColor(), $colorspace); - $border_color = $this->colorToPixel($this->getBorderColor(), $colorspace); + $background_color = $this->driver()->colorToNative( + $this->backgroundColor(), + $image->colorspace() + ); - return $image->mapFrames(function ($frame) use ($background_color, $border_color) { + $border_color = $this->driver()->colorToNative( + $this->borderColor(), + $image->colorspace() + ); + + foreach ($image as $frame) { $drawing = new ImagickDraw(); $drawing->setFillColor($background_color); - if ($this->ellipse()->hasBorder()) { - $drawing->setStrokeWidth($this->ellipse()->getBorderSize()); + if ($this->drawable->hasBorder()) { + $drawing->setStrokeWidth($this->drawable->borderSize()); $drawing->setStrokeColor($border_color); } $drawing->ellipse( - $this->position->x(), - $this->position->y(), - $this->ellipse()->getWidth() / 2, - $this->ellipse()->getHeight() / 2, + $this->position()->x(), + $this->position()->y(), + $this->drawable->width() / 2, + $this->drawable->height() / 2, 0, 360 ); - $frame->core()->drawImage($drawing); - }); + $frame->data()->drawImage($drawing); + } + + return $image; } } diff --git a/src/Drivers/Imagick/Modifiers/DrawLineModifier.php b/src/Drivers/Imagick/Modifiers/DrawLineModifier.php index e091c8c7..ca890b4b 100644 --- a/src/Drivers/Imagick/Modifiers/DrawLineModifier.php +++ b/src/Drivers/Imagick/Modifiers/DrawLineModifier.php @@ -3,32 +3,33 @@ namespace Intervention\Image\Drivers\Imagick\Modifiers; use ImagickDraw; -use Intervention\Image\Drivers\Abstract\Modifiers\AbstractDrawModifier; -use Intervention\Image\Drivers\Imagick\Traits\CanHandleColors; +use Intervention\Image\Drivers\DrawModifier; use Intervention\Image\Interfaces\ImageInterface; -use Intervention\Image\Interfaces\ModifierInterface; -class DrawLineModifier extends AbstractDrawModifier implements ModifierInterface +class DrawLineModifier extends DrawModifier { - use CanHandleColors; - public function apply(ImageInterface $image): ImageInterface { $drawing = new ImagickDraw(); - $drawing->setStrokeWidth($this->line()->getWidth()); + $drawing->setStrokeWidth($this->drawable->getWidth()); $drawing->setStrokeColor( - $this->colorToPixel($this->getBackgroundColor(), $image->colorspace()) + $this->driver()->colorToNative( + $this->backgroundColor(), + $image->colorspace() + ) ); $drawing->line( - $this->line()->getStart()->x(), - $this->line()->getStart()->y(), - $this->line()->getEnd()->x(), - $this->line()->getEnd()->y(), + $this->drawable->getStart()->x(), + $this->drawable->getStart()->y(), + $this->drawable->getEnd()->x(), + $this->drawable->getEnd()->y(), ); - return $image->mapFrames(function ($frame) use ($drawing) { - $frame->core()->drawImage($drawing); - }); + foreach ($image as $frame) { + $frame->data()->drawImage($drawing); + } + + return $image; } } diff --git a/src/Drivers/Imagick/Modifiers/DrawPixelModifier.php b/src/Drivers/Imagick/Modifiers/DrawPixelModifier.php index 3c803cc7..01121fdd 100644 --- a/src/Drivers/Imagick/Modifiers/DrawPixelModifier.php +++ b/src/Drivers/Imagick/Modifiers/DrawPixelModifier.php @@ -3,38 +3,26 @@ namespace Intervention\Image\Drivers\Imagick\Modifiers; use ImagickDraw; -use Intervention\Image\Drivers\Imagick\Traits\CanHandleColors; -use Intervention\Image\Geometry\Point; -use Intervention\Image\Interfaces\ColorInterface; +use Intervention\Image\Drivers\DriverModifier; use Intervention\Image\Interfaces\ImageInterface; -use Intervention\Image\Interfaces\ModifierInterface; -use Intervention\Image\Traits\CanCheckType; -use Intervention\Image\Traits\CanHandleInput; -class DrawPixelModifier implements ModifierInterface +class DrawPixelModifier extends DriverModifier { - use CanHandleInput; - use CanHandleColors; - use CanCheckType; - - public function __construct(protected Point $position, protected mixed $color) - { - // - } - public function apply(ImageInterface $image): ImageInterface { - $color = $this->failIfNotInstance( - $this->handleInput($this->color), - ColorInterface::class + $color = $this->driver()->colorToNative( + $this->driver()->handleInput($this->color), + $image->colorspace() ); $pixel = new ImagickDraw(); - $pixel->setFillColor($this->colorToPixel($color, $image->colorspace())); + $pixel->setFillColor($color); $pixel->point($this->position->x(), $this->position->y()); - return $image->mapFrames(function ($frame) use ($pixel) { - $frame->core()->drawImage($pixel); - }); + foreach ($image as $frame) { + $frame->data()->drawImage($pixel); + } + + return $image; } } diff --git a/src/Drivers/Imagick/Modifiers/DrawPolygonModifier.php b/src/Drivers/Imagick/Modifiers/DrawPolygonModifier.php index d0f06953..f1069583 100644 --- a/src/Drivers/Imagick/Modifiers/DrawPolygonModifier.php +++ b/src/Drivers/Imagick/Modifiers/DrawPolygonModifier.php @@ -3,49 +3,47 @@ namespace Intervention\Image\Drivers\Imagick\Modifiers; use ImagickDraw; -use Intervention\Image\Drivers\Abstract\Modifiers\AbstractDrawModifier; -use Intervention\Image\Drivers\Imagick\Traits\CanHandleColors; -use Intervention\Image\Interfaces\DrawableInterface; +use Intervention\Image\Drivers\DrawModifier; use Intervention\Image\Interfaces\ImageInterface; -use Intervention\Image\Interfaces\ModifierInterface; -class DrawPolygonModifier extends AbstractDrawModifier implements ModifierInterface +class DrawPolygonModifier extends DrawModifier { - use CanHandleColors; - - public function __construct( - protected DrawableInterface $drawable - ) { - // - } - public function apply(ImageInterface $image): ImageInterface { $drawing = new ImagickDraw(); - $colorspace = $image->colorspace(); - $background_color = $this->colorToPixel($this->getBackgroundColor(), $colorspace); - $border_color = $this->colorToPixel($this->getBorderColor(), $colorspace); - if ($this->polygon()->hasBackgroundColor()) { + if ($this->drawable->hasBackgroundColor()) { + $background_color = $this->driver()->colorToNative( + $this->backgroundColor(), + $image->colorspace() + ); + $drawing->setFillColor($background_color); } - if ($this->polygon()->hasBorder()) { + if ($this->drawable->hasBorder()) { + $border_color = $this->driver()->colorToNative( + $this->borderColor(), + $image->colorspace() + ); + $drawing->setStrokeColor($border_color); - $drawing->setStrokeWidth($this->polygon()->getBorderSize()); + $drawing->setStrokeWidth($this->drawable->borderSize()); } $drawing->polygon($this->points()); - return $image->mapFrames(function ($frame) use ($drawing) { - $frame->core()->drawImage($drawing); - }); + foreach ($image as $frame) { + $frame->data()->drawImage($drawing); + } + + return $image; } private function points(): array { $points = []; - foreach ($this->polygon() as $point) { + foreach ($this->drawable as $point) { $points[] = ['x' => $point->x(), 'y' => $point->y()]; } diff --git a/src/Drivers/Imagick/Modifiers/DrawRectangleModifier.php b/src/Drivers/Imagick/Modifiers/DrawRectangleModifier.php index 8c859aef..2a8f7249 100644 --- a/src/Drivers/Imagick/Modifiers/DrawRectangleModifier.php +++ b/src/Drivers/Imagick/Modifiers/DrawRectangleModifier.php @@ -3,38 +3,43 @@ namespace Intervention\Image\Drivers\Imagick\Modifiers; use ImagickDraw; -use Intervention\Image\Drivers\Abstract\Modifiers\AbstractDrawModifier; -use Intervention\Image\Drivers\Imagick\Traits\CanHandleColors; +use Intervention\Image\Drivers\DrawModifier; use Intervention\Image\Interfaces\ImageInterface; -use Intervention\Image\Interfaces\ModifierInterface; -class DrawRectangleModifier extends AbstractDrawModifier implements ModifierInterface +class DrawRectangleModifier extends DrawModifier { - use CanHandleColors; - public function apply(ImageInterface $image): ImageInterface { $drawing = new ImagickDraw(); - $colorspace = $image->colorspace(); - $background_color = $this->colorToPixel($this->getBackgroundColor(), $colorspace); - $border_color = $this->colorToPixel($this->getBorderColor(), $colorspace); + + $background_color = $this->driver()->colorToNative( + $this->backgroundColor(), + $image->colorspace(), + ); + + $border_color = $this->driver()->colorToNative( + $this->borderColor(), + $image->colorspace(), + ); $drawing->setFillColor($background_color); - if ($this->rectangle()->hasBorder()) { + if ($this->drawable->hasBorder()) { $drawing->setStrokeColor($border_color); - $drawing->setStrokeWidth($this->rectangle()->getBorderSize()); + $drawing->setStrokeWidth($this->drawable->borderSize()); } // build rectangle $drawing->rectangle( $this->position->x(), $this->position->y(), - $this->position->x() + $this->rectangle()->bottomRightPoint()->x(), - $this->position->y() + $this->rectangle()->bottomRightPoint()->y() + $this->position->x() + $this->drawable->width(), + $this->position->y() + $this->drawable->height() ); - return $image->mapFrames(function ($frame) use ($drawing) { - $frame->core()->drawImage($drawing); - }); + foreach ($image as $frame) { + $frame->data()->drawImage($drawing); + } + + return $image; } } diff --git a/src/Drivers/Imagick/Modifiers/FillModifier.php b/src/Drivers/Imagick/Modifiers/FillModifier.php index c7f482cd..80e5a5c9 100644 --- a/src/Drivers/Imagick/Modifiers/FillModifier.php +++ b/src/Drivers/Imagick/Modifiers/FillModifier.php @@ -5,27 +5,16 @@ namespace Intervention\Image\Drivers\Imagick\Modifiers; use Imagick; use ImagickDraw; use ImagickPixel; +use Intervention\Image\Drivers\DriverModifier; use Intervention\Image\Drivers\Imagick\Frame; -use Intervention\Image\Drivers\Imagick\Traits\CanHandleColors; -use Intervention\Image\Geometry\Point; -use Intervention\Image\Interfaces\ColorInterface; use Intervention\Image\Interfaces\ImageInterface; -use Intervention\Image\Interfaces\ModifierInterface; -class FillModifier implements ModifierInterface +class FillModifier extends DriverModifier { - use CanHandleColors; - - public function __construct( - protected ColorInterface $color, - protected ?Point $position = null - ) { - // - } - public function apply(ImageInterface $image): ImageInterface { - $pixel = $this->colorToPixel($this->color, $image->colorspace()); + $color = $this->driver()->handleInput($this->color); + $pixel = $this->driver()->colorToNative($color, $image->colorspace()); foreach ($image as $frame) { if ($this->hasPosition()) { @@ -38,14 +27,14 @@ class FillModifier implements ModifierInterface return $image; } - protected function floodFillWithColor(Frame $frame, ImagickPixel $pixel): void + private function floodFillWithColor(Frame $frame, ImagickPixel $pixel): void { - $target = $frame->core()->getImagePixelColor( + $target = $frame->data()->getImagePixelColor( $this->position->x(), $this->position->y() ); - $frame->core()->floodfillPaintImage( + $frame->data()->floodfillPaintImage( $pixel, 100, $target, @@ -56,21 +45,16 @@ class FillModifier implements ModifierInterface ); } - protected function fillAllWithColor(Frame $frame, ImagickPixel $pixel): void + private function fillAllWithColor(Frame $frame, ImagickPixel $pixel): void { $draw = new ImagickDraw(); $draw->setFillColor($pixel); $draw->rectangle( 0, 0, - $frame->core()->getImageWidth(), - $frame->core()->getImageHeight() + $frame->data()->getImageWidth(), + $frame->data()->getImageHeight() ); - $frame->core()->drawImage($draw); - } - - protected function hasPosition(): bool - { - return !empty($this->position); + $frame->data()->drawImage($draw); } } diff --git a/src/Drivers/Imagick/Modifiers/FitDownModifier.php b/src/Drivers/Imagick/Modifiers/FitDownModifier.php index 73e26ef7..f6bd9f5c 100644 --- a/src/Drivers/Imagick/Modifiers/FitDownModifier.php +++ b/src/Drivers/Imagick/Modifiers/FitDownModifier.php @@ -6,7 +6,7 @@ use Intervention\Image\Interfaces\SizeInterface; class FitDownModifier extends FitModifier { - protected function getResizeSize(SizeInterface $size): SizeInterface + public function getResizeSize(SizeInterface $size): SizeInterface { return $size->scaleDown($this->width, $this->height); } diff --git a/src/Drivers/Imagick/Modifiers/FitModifier.php b/src/Drivers/Imagick/Modifiers/FitModifier.php index 4e6c74a4..c1ca6481 100644 --- a/src/Drivers/Imagick/Modifiers/FitModifier.php +++ b/src/Drivers/Imagick/Modifiers/FitModifier.php @@ -2,11 +2,10 @@ namespace Intervention\Image\Drivers\Imagick\Modifiers; -use Intervention\Image\Drivers\Abstract\Modifiers\AbstractFitModifier; +use Intervention\Image\Drivers\DriverModifier; use Intervention\Image\Interfaces\ImageInterface; -use Intervention\Image\Interfaces\ModifierInterface; -class FitModifier extends AbstractFitModifier implements ModifierInterface +class FitModifier extends DriverModifier { public function apply(ImageInterface $image): ImageInterface { @@ -14,14 +13,14 @@ class FitModifier extends AbstractFitModifier implements ModifierInterface $resize = $this->getResizeSize($crop); foreach ($image as $frame) { - $frame->core()->extentImage( + $frame->data()->extentImage( $crop->width(), $crop->height(), $crop->pivot()->x(), $crop->pivot()->y() ); - $frame->core()->scaleImage( + $frame->data()->scaleImage( $resize->width(), $resize->height() ); diff --git a/src/Drivers/Imagick/Modifiers/FlipModifier.php b/src/Drivers/Imagick/Modifiers/FlipModifier.php index 24159ea4..fa2f2cba 100644 --- a/src/Drivers/Imagick/Modifiers/FlipModifier.php +++ b/src/Drivers/Imagick/Modifiers/FlipModifier.php @@ -2,15 +2,15 @@ namespace Intervention\Image\Drivers\Imagick\Modifiers; +use Intervention\Image\Drivers\DriverModifier; use Intervention\Image\Interfaces\ImageInterface; -use Intervention\Image\Interfaces\ModifierInterface; -class FlipModifier implements ModifierInterface +class FlipModifier extends DriverModifier { public function apply(ImageInterface $image): ImageInterface { foreach ($image as $frame) { - $frame->core()->flipImage(); + $frame->data()->flipImage(); } return $image; diff --git a/src/Drivers/Imagick/Modifiers/FlopModifier.php b/src/Drivers/Imagick/Modifiers/FlopModifier.php index 91f392e3..4e74bf76 100644 --- a/src/Drivers/Imagick/Modifiers/FlopModifier.php +++ b/src/Drivers/Imagick/Modifiers/FlopModifier.php @@ -2,15 +2,15 @@ namespace Intervention\Image\Drivers\Imagick\Modifiers; +use Intervention\Image\Drivers\DriverModifier; use Intervention\Image\Interfaces\ImageInterface; -use Intervention\Image\Interfaces\ModifierInterface; -class FlopModifier implements ModifierInterface +class FlopModifier extends DriverModifier { public function apply(ImageInterface $image): ImageInterface { foreach ($image as $frame) { - $frame->core()->flopImage(); + $frame->data()->flopImage(); } return $image; diff --git a/src/Drivers/Imagick/Modifiers/GammaModifier.php b/src/Drivers/Imagick/Modifiers/GammaModifier.php index db2bbb56..59fba86e 100644 --- a/src/Drivers/Imagick/Modifiers/GammaModifier.php +++ b/src/Drivers/Imagick/Modifiers/GammaModifier.php @@ -2,20 +2,15 @@ namespace Intervention\Image\Drivers\Imagick\Modifiers; +use Intervention\Image\Drivers\DriverModifier; use Intervention\Image\Interfaces\ImageInterface; -use Intervention\Image\Interfaces\ModifierInterface; -class GammaModifier implements ModifierInterface +class GammaModifier extends DriverModifier { - public function __construct(protected float $gamma) - { - // - } - public function apply(ImageInterface $image): ImageInterface { foreach ($image as $frame) { - $frame->core()->gammaImage($this->gamma); + $frame->data()->gammaImage($this->gamma); } return $image; diff --git a/src/Drivers/Imagick/Modifiers/GreyscaleModifier.php b/src/Drivers/Imagick/Modifiers/GreyscaleModifier.php index 5c5f6883..ff398aab 100644 --- a/src/Drivers/Imagick/Modifiers/GreyscaleModifier.php +++ b/src/Drivers/Imagick/Modifiers/GreyscaleModifier.php @@ -2,15 +2,15 @@ namespace Intervention\Image\Drivers\Imagick\Modifiers; +use Intervention\Image\Drivers\DriverModifier; use Intervention\Image\Interfaces\ImageInterface; -use Intervention\Image\Interfaces\ModifierInterface; -class GreyscaleModifier implements ModifierInterface +class GreyscaleModifier extends DriverModifier { public function apply(ImageInterface $image): ImageInterface { foreach ($image as $frame) { - $frame->core()->modulateImage(100, 0, 100); + $frame->data()->modulateImage(100, 0, 100); } return $image; diff --git a/src/Drivers/Imagick/Modifiers/InvertModifier.php b/src/Drivers/Imagick/Modifiers/InvertModifier.php index 73191574..0787c240 100644 --- a/src/Drivers/Imagick/Modifiers/InvertModifier.php +++ b/src/Drivers/Imagick/Modifiers/InvertModifier.php @@ -2,15 +2,15 @@ namespace Intervention\Image\Drivers\Imagick\Modifiers; +use Intervention\Image\Drivers\DriverModifier; use Intervention\Image\Interfaces\ImageInterface; -use Intervention\Image\Interfaces\ModifierInterface; -class InvertModifier implements ModifierInterface +class InvertModifier extends DriverModifier { public function apply(ImageInterface $image): ImageInterface { foreach ($image as $frame) { - $frame->core()->negateImage(false); + $frame->data()->negateImage(false); } return $image; diff --git a/src/Drivers/Imagick/Modifiers/LimitColorsModifier.php b/src/Drivers/Imagick/Modifiers/LimitColorsModifier.php index 142794f5..0b8b5ad3 100644 --- a/src/Drivers/Imagick/Modifiers/LimitColorsModifier.php +++ b/src/Drivers/Imagick/Modifiers/LimitColorsModifier.php @@ -2,20 +2,11 @@ namespace Intervention\Image\Drivers\Imagick\Modifiers; +use Intervention\Image\Drivers\DriverModifier; use Intervention\Image\Interfaces\ImageInterface; -use Intervention\Image\Interfaces\ModifierInterface; -use Intervention\Image\Traits\CanCheckType; -use Intervention\Image\Drivers\Imagick\Image; -class LimitColorsModifier implements ModifierInterface +class LimitColorsModifier extends DriverModifier { - use CanCheckType; - - public function __construct(protected int $limit = 0, protected $threshold = 256) - { - // - } - public function apply(ImageInterface $image): ImageInterface { // no color limit: no reduction @@ -28,11 +19,10 @@ class LimitColorsModifier implements ModifierInterface return $image; } - $image = $this->failIfNotClass($image, Image::class); - foreach ($image->getImagick() as $core) { - $core->quantizeImage( + foreach ($image as $frame) { + $frame->data()->quantizeImage( $this->limit, - $core->getImageColorspace(), + $frame->data()->getImageColorspace(), 0, false, false diff --git a/src/Drivers/Imagick/Modifiers/PadDownModifier.php b/src/Drivers/Imagick/Modifiers/PadDownModifier.php index 709dc0a3..4cd35e59 100644 --- a/src/Drivers/Imagick/Modifiers/PadDownModifier.php +++ b/src/Drivers/Imagick/Modifiers/PadDownModifier.php @@ -2,24 +2,6 @@ namespace Intervention\Image\Drivers\Imagick\Modifiers; -use Intervention\Image\Geometry\Rectangle; -use Intervention\Image\Interfaces\ImageInterface; -use Intervention\Image\Interfaces\SizeInterface; - class PadDownModifier extends PadModifier { - protected function getCropSize(ImageInterface $image): SizeInterface - { - $resize = $this->getResizeSize($image); - - return $image->size() - ->contain($resize->width(), $resize->height()) - ->alignPivotTo($resize, $this->position); - } - - protected function getResizeSize(ImageInterface $image): SizeInterface - { - return (new Rectangle($this->width, $this->height)) - ->resizeDown($image->width(), $image->height()); - } } diff --git a/src/Drivers/Imagick/Modifiers/PadModifier.php b/src/Drivers/Imagick/Modifiers/PadModifier.php index acbae81d..8f884332 100644 --- a/src/Drivers/Imagick/Modifiers/PadModifier.php +++ b/src/Drivers/Imagick/Modifiers/PadModifier.php @@ -5,34 +5,26 @@ namespace Intervention\Image\Drivers\Imagick\Modifiers; use Imagick; use ImagickDraw; use ImagickPixel; -use Intervention\Image\Drivers\Imagick\Image; -use Intervention\Image\Drivers\Abstract\Modifiers\AbstractPadModifier; use Intervention\Image\Colors\Rgb\Color; -use Intervention\Image\Drivers\Imagick\Traits\CanHandleColors; +use Intervention\Image\Drivers\DriverModifier; +use Intervention\Image\Drivers\Imagick\Core; +use Intervention\Image\Image; use Intervention\Image\Interfaces\ImageInterface; -use Intervention\Image\Interfaces\ModifierInterface; use Intervention\Image\Interfaces\SizeInterface; -use Intervention\Image\Traits\CanBuildNewImage; -use Intervention\Image\Traits\CanHandleInput; +use Intervention\Image\Modifiers\FillModifier; -class PadModifier extends AbstractPadModifier implements ModifierInterface +class PadModifier extends DriverModifier { - use CanBuildNewImage; - use CanHandleInput; - use CanHandleColors; - public function apply(ImageInterface $image): ImageInterface { - $image = $this->failIfNotClass($image, Image::class); - - $resize = $this->getResizeSize($image); $crop = $this->getCropSize($image); - $background = $this->handleInput($this->background); + $resize = $this->getResizeSize($image); + $background = $this->driver()->handleInput($this->background); $imagick = new Imagick(); foreach ($image as $frame) { // resize current core - $frame->core()->scaleImage( + $frame->data()->scaleImage( $crop->width(), $crop->height() ); @@ -42,7 +34,7 @@ class PadModifier extends AbstractPadModifier implements ModifierInterface // place current core onto canvas $canvas->compositeImage( - $frame->core(), + $frame->data(), Imagick::COMPOSITE_DEFAULT, $crop->pivot()->x(), $crop->pivot()->y() @@ -51,17 +43,22 @@ class PadModifier extends AbstractPadModifier implements ModifierInterface $imagick->addImage($canvas); } - return $image->setImagick($imagick); + return new Image( + $image->driver(), + new Core($imagick), + $image->exif() + ); } protected function buildBaseCanvas(SizeInterface $crop, SizeInterface $resize, Color $background): Imagick { // build base canvas in target size - $canvas = $this->imageFactory()->newCore( + $canvas = $this->driver()->createImage( $resize->width(), - $resize->height(), - $background - ); + $resize->height() + )->modify( + new FillModifier($background) + )->core()->native(); // make area where image is placed transparent to keep // transparency even if background-color is set diff --git a/src/Drivers/Imagick/Modifiers/PixelateModifier.php b/src/Drivers/Imagick/Modifiers/PixelateModifier.php index e05ebf0f..b811df2f 100644 --- a/src/Drivers/Imagick/Modifiers/PixelateModifier.php +++ b/src/Drivers/Imagick/Modifiers/PixelateModifier.php @@ -2,17 +2,12 @@ namespace Intervention\Image\Drivers\Imagick\Modifiers; +use Intervention\Image\Drivers\DriverModifier; use Intervention\Image\Drivers\Imagick\Frame; use Intervention\Image\Interfaces\ImageInterface; -use Intervention\Image\Interfaces\ModifierInterface; -class PixelateModifier implements ModifierInterface +class PixelateModifier extends DriverModifier { - public function __construct(protected int $size) - { - // - } - public function apply(ImageInterface $image): ImageInterface { foreach ($image as $frame) { @@ -26,11 +21,11 @@ class PixelateModifier implements ModifierInterface { $size = $frame->size(); - $frame->core()->scaleImage( + $frame->data()->scaleImage( round(max(1, ($size->width() / $this->size))), round(max(1, ($size->height() / $this->size))) ); - $frame->core()->scaleImage($size->width(), $size->height()); + $frame->data()->scaleImage($size->width(), $size->height()); } } diff --git a/src/Drivers/Imagick/Modifiers/PlaceModifier.php b/src/Drivers/Imagick/Modifiers/PlaceModifier.php index fb6d0358..57946443 100644 --- a/src/Drivers/Imagick/Modifiers/PlaceModifier.php +++ b/src/Drivers/Imagick/Modifiers/PlaceModifier.php @@ -3,33 +3,19 @@ namespace Intervention\Image\Drivers\Imagick\Modifiers; use Imagick; -use Intervention\Image\Drivers\Imagick\Image; +use Intervention\Image\Drivers\DriverModifier; use Intervention\Image\Interfaces\ImageInterface; -use Intervention\Image\Interfaces\ModifierInterface; -use Intervention\Image\Interfaces\PointInterface; -use Intervention\Image\Traits\CanHandleInput; -class PlaceModifier implements ModifierInterface +class PlaceModifier extends DriverModifier { - use CanHandleInput; - - public function __construct( - protected $element, - protected string $position, - protected int $offset_x, - protected int $offset_y - ) { - // - } - public function apply(ImageInterface $image): ImageInterface { - $watermark = $this->handleInput($this->element); + $watermark = $this->driver()->handleInput($this->element); $position = $this->getPosition($image, $watermark); foreach ($image as $frame) { - $frame->core()->compositeImage( - $watermark->frame()->core(), + $frame->data()->compositeImage( + $watermark->core()->native(), Imagick::COMPOSITE_DEFAULT, $position->x(), $position->y() @@ -38,12 +24,4 @@ class PlaceModifier implements ModifierInterface return $image; } - - protected function getPosition(ImageInterface $image, Image $watermark): PointInterface - { - $image_size = $image->size()->movePivot($this->position, $this->offset_x, $this->offset_y); - $watermark_size = $watermark->size()->movePivot($this->position); - - return $image_size->relativePositionTo($watermark_size); - } } diff --git a/src/Drivers/Imagick/Modifiers/ProfileModifier.php b/src/Drivers/Imagick/Modifiers/ProfileModifier.php index bf0ae013..fad1a471 100644 --- a/src/Drivers/Imagick/Modifiers/ProfileModifier.php +++ b/src/Drivers/Imagick/Modifiers/ProfileModifier.php @@ -2,25 +2,15 @@ namespace Intervention\Image\Drivers\Imagick\Modifiers; -use Intervention\Image\Colors\Profile; -use Intervention\Image\Drivers\Imagick\Image; +use Intervention\Image\Drivers\DriverModifier; use Intervention\Image\Exceptions\ColorException; use Intervention\Image\Interfaces\ImageInterface; -use Intervention\Image\Interfaces\ModifierInterface; -use Intervention\Image\Traits\CanCheckType; -class ProfileModifier implements ModifierInterface +class ProfileModifier extends DriverModifier { - use CanCheckType; - - public function __construct(protected Profile $profile) - { - // - } - public function apply(ImageInterface $image): ImageInterface { - $imagick = $this->failIfNotClass($image, Image::class)->getImagick(); + $imagick = $image->core()->native(); $result = $imagick->profileImage('icc', (string) $this->profile); if ($result === false) { diff --git a/src/Drivers/Imagick/Modifiers/ProfileRemovalModifier.php b/src/Drivers/Imagick/Modifiers/ProfileRemovalModifier.php index 7a4583f2..d037ac1c 100644 --- a/src/Drivers/Imagick/Modifiers/ProfileRemovalModifier.php +++ b/src/Drivers/Imagick/Modifiers/ProfileRemovalModifier.php @@ -2,19 +2,15 @@ namespace Intervention\Image\Drivers\Imagick\Modifiers; -use Intervention\Image\Drivers\Imagick\Image; +use Intervention\Image\Drivers\DriverModifier; use Intervention\Image\Exceptions\ColorException; use Intervention\Image\Interfaces\ImageInterface; -use Intervention\Image\Interfaces\ModifierInterface; -use Intervention\Image\Traits\CanCheckType; -class ProfileRemovalModifier implements ModifierInterface +class ProfileRemovalModifier extends DriverModifier { - use CanCheckType; - public function apply(ImageInterface $image): ImageInterface { - $imagick = $this->failIfNotClass($image, Image::class)->getImagick(); + $imagick = $image->core()->native(); $result = $imagick->profileImage('icc', null); if ($result === false) { diff --git a/src/Drivers/Imagick/Modifiers/RemoveAnimationModifier.php b/src/Drivers/Imagick/Modifiers/RemoveAnimationModifier.php index 025d91b1..42072849 100644 --- a/src/Drivers/Imagick/Modifiers/RemoveAnimationModifier.php +++ b/src/Drivers/Imagick/Modifiers/RemoveAnimationModifier.php @@ -3,29 +3,24 @@ namespace Intervention\Image\Drivers\Imagick\Modifiers; use Imagick; -use Intervention\Image\Drivers\Abstract\Modifiers\AbstractRemoveAnimationModifier; +use Intervention\Image\Drivers\DriverModifier; +use Intervention\Image\Drivers\Imagick\Core; +use Intervention\Image\Image; use Intervention\Image\Interfaces\ImageInterface; -use Intervention\Image\Drivers\Imagick\Image; -use Intervention\Image\Traits\CanCheckType; -class RemoveAnimationModifier extends AbstractRemoveAnimationModifier +class RemoveAnimationModifier extends DriverModifier { - use CanCheckType; - - public function __construct(protected int|string $position = 0) - { - // - } - public function apply(ImageInterface $image): ImageInterface { - $image = $this->failIfNotClass($image, Image::class); - // create new imagick with just one image $imagick = new Imagick(); $frame = $this->chosenFrame($image, $this->position); - $imagick->addImage($frame->core()->getImage()); + $imagick->addImage($frame->data()->getImage()); - return $image->setImagick($imagick); + return new Image( + $image->driver(), + new Core($imagick), + $image->exif() + ); } } diff --git a/src/Drivers/Imagick/Modifiers/ResizeModifier.php b/src/Drivers/Imagick/Modifiers/ResizeModifier.php index b4314e79..948f79ae 100644 --- a/src/Drivers/Imagick/Modifiers/ResizeModifier.php +++ b/src/Drivers/Imagick/Modifiers/ResizeModifier.php @@ -2,23 +2,18 @@ namespace Intervention\Image\Drivers\Imagick\Modifiers; +use Intervention\Image\Drivers\DriverModifier; use Intervention\Image\Interfaces\ImageInterface; -use Intervention\Image\Interfaces\ModifierInterface; use Intervention\Image\Interfaces\SizeInterface; -class ResizeModifier implements ModifierInterface +class ResizeModifier extends DriverModifier { - public function __construct(protected ?int $width = null, protected ?int $height = null) - { - // - } - public function apply(ImageInterface $image): ImageInterface { $resizeTo = $this->getAdjustedSize($image); foreach ($image as $frame) { - $frame->core()->scaleImage( + $frame->data()->scaleImage( $resizeTo->width(), $resizeTo->height() ); diff --git a/src/Drivers/Imagick/Modifiers/ResolutionModifier.php b/src/Drivers/Imagick/Modifiers/ResolutionModifier.php index e4166b94..b00f2a17 100644 --- a/src/Drivers/Imagick/Modifiers/ResolutionModifier.php +++ b/src/Drivers/Imagick/Modifiers/ResolutionModifier.php @@ -2,23 +2,14 @@ namespace Intervention\Image\Drivers\Imagick\Modifiers; +use Intervention\Image\Drivers\DriverModifier; use Intervention\Image\Interfaces\ImageInterface; -use Intervention\Image\Interfaces\ModifierInterface; -use Intervention\Image\Drivers\Imagick\Image; -use Intervention\Image\Traits\CanCheckType; -class ResolutionModifier implements ModifierInterface +class ResolutionModifier extends DriverModifier { - use CanCheckType; - - public function __construct(protected float $x, protected float $y) - { - // - } - public function apply(ImageInterface $image): ImageInterface { - $imagick = $this->failIfNotClass($image, Image::class)->getImagick(); + $imagick = $image->core()->native(); $imagick->setImageResolution($this->x, $this->y); return $image; diff --git a/src/Drivers/Imagick/Modifiers/RotateModifier.php b/src/Drivers/Imagick/Modifiers/RotateModifier.php index 58acaa4a..c8d0a8dd 100644 --- a/src/Drivers/Imagick/Modifiers/RotateModifier.php +++ b/src/Drivers/Imagick/Modifiers/RotateModifier.php @@ -2,29 +2,25 @@ namespace Intervention\Image\Drivers\Imagick\Modifiers; -use Intervention\Image\Drivers\Abstract\Modifiers\AbstractRotateModifier; -use Intervention\Image\Drivers\Imagick\Traits\CanHandleColors; +use Intervention\Image\Drivers\DriverModifier; use Intervention\Image\Interfaces\ImageInterface; -use Intervention\Image\Interfaces\ModifierInterface; -class RotateModifier extends AbstractRotateModifier implements ModifierInterface +class RotateModifier extends DriverModifier { - use CanHandleColors; - public function apply(ImageInterface $image): ImageInterface { + $background = $this->driver()->colorToNative( + $this->driver()->handleInput($this->background), + $image->colorspace() + ); + foreach ($image as $frame) { - $frame->core()->rotateImage( - $this->colorToPixel($this->backgroundColor(), $image->colorspace()), - $this->rotationAngle() + $frame->data()->rotateImage( + $background, + $this->rotationAngle() * -1 ); } return $image; } - - protected function rotationAngle(): float - { - return parent::rotationAngle() * -1; - } } diff --git a/src/Drivers/Imagick/Modifiers/SharpenModifier.php b/src/Drivers/Imagick/Modifiers/SharpenModifier.php index 3259909e..6f91f929 100644 --- a/src/Drivers/Imagick/Modifiers/SharpenModifier.php +++ b/src/Drivers/Imagick/Modifiers/SharpenModifier.php @@ -2,20 +2,15 @@ namespace Intervention\Image\Drivers\Imagick\Modifiers; +use Intervention\Image\Drivers\DriverModifier; use Intervention\Image\Interfaces\ImageInterface; -use Intervention\Image\Interfaces\ModifierInterface; -class SharpenModifier implements ModifierInterface +class SharpenModifier extends DriverModifier { - public function __construct(protected int $amount) - { - // - } - public function apply(ImageInterface $image): ImageInterface { foreach ($image as $frame) { - $frame->core()->unsharpMaskImage(1, 1, $this->amount / 6.25, 0); + $frame->data()->unsharpMaskImage(1, 1, $this->amount / 6.25, 0); } return $image; diff --git a/src/Drivers/Imagick/Modifiers/TextWriter.php b/src/Drivers/Imagick/Modifiers/TextWriter.php index 24e7f1b0..b14e5c12 100644 --- a/src/Drivers/Imagick/Modifiers/TextWriter.php +++ b/src/Drivers/Imagick/Modifiers/TextWriter.php @@ -2,20 +2,19 @@ namespace Intervention\Image\Drivers\Imagick\Modifiers; -use Intervention\Image\Drivers\Abstract\AbstractTextWriter; -use Intervention\Image\Drivers\Imagick\Font; +use Intervention\Image\Drivers\DriverModifier; use Intervention\Image\Interfaces\ImageInterface; -class TextWriter extends AbstractTextWriter +class TextWriter extends DriverModifier { public function apply(ImageInterface $image): ImageInterface { $lines = $this->getAlignedTextBlock(); - $font = $this->failIfNotClass($this->getFont(), Font::class); + $font = $this->font; foreach ($image as $frame) { foreach ($lines as $line) { - $frame->core()->annotateImage( + $frame->data()->annotateImage( $font->toImagickDraw($image->colorspace()), $line->getPosition()->x(), $line->getPosition()->y(), diff --git a/src/EncodedImage.php b/src/EncodedImage.php index 4ad71b88..7f65d455 100644 --- a/src/EncodedImage.php +++ b/src/EncodedImage.php @@ -16,7 +16,6 @@ class EncodedImage extends GenericData implements EncodedImageInterface protected string $data, protected string $mimetype = 'application/octet-stream' ) { - // } /** diff --git a/src/Encoders/AvifEncoder.php b/src/Encoders/AvifEncoder.php new file mode 100644 index 00000000..d7465661 --- /dev/null +++ b/src/Encoders/AvifEncoder.php @@ -0,0 +1,19 @@ +encode($this); + } +} diff --git a/src/Encoders/BmpEncoder.php b/src/Encoders/BmpEncoder.php new file mode 100644 index 00000000..d78556a3 --- /dev/null +++ b/src/Encoders/BmpEncoder.php @@ -0,0 +1,19 @@ +encode($this); + } +} diff --git a/src/Encoders/GifEncoder.php b/src/Encoders/GifEncoder.php new file mode 100644 index 00000000..1aff134e --- /dev/null +++ b/src/Encoders/GifEncoder.php @@ -0,0 +1,19 @@ +encode($this); + } +} diff --git a/src/Encoders/JpegEncoder.php b/src/Encoders/JpegEncoder.php new file mode 100644 index 00000000..2ecafb94 --- /dev/null +++ b/src/Encoders/JpegEncoder.php @@ -0,0 +1,19 @@ +encode($this); + } +} diff --git a/src/Encoders/PngEncoder.php b/src/Encoders/PngEncoder.php new file mode 100644 index 00000000..efd1d78b --- /dev/null +++ b/src/Encoders/PngEncoder.php @@ -0,0 +1,19 @@ +encode($this); + } +} diff --git a/src/Encoders/WebpEncoder.php b/src/Encoders/WebpEncoder.php new file mode 100644 index 00000000..2bed404c --- /dev/null +++ b/src/Encoders/WebpEncoder.php @@ -0,0 +1,19 @@ +encode($this); + } +} diff --git a/src/Geometry/Circle.php b/src/Geometry/Circle.php index 4e482582..06d10757 100644 --- a/src/Geometry/Circle.php +++ b/src/Geometry/Circle.php @@ -14,11 +14,6 @@ class Circle extends Ellipse $this->setHeight($diameter); } - public function diameter(int $diameter): self - { - return $this->setDiameter($diameter); - } - public function setDiameter(int $diameter): self { $this->setWidth($diameter); @@ -27,22 +22,17 @@ class Circle extends Ellipse return $this; } - public function getDiameter(): int + public function diameter(): int { return $this->diameter; } - public function radius(int $radius): self - { - return $this->setRadius($radius); - } - public function setRadius(int $radius): self { - return $this->diameter(intval($radius * 2)); + return $this->setDiameter(intval($radius * 2)); } - public function getRadius(): int + public function radius(): int { return intval($this->diameter / 2); } diff --git a/src/Geometry/Ellipse.php b/src/Geometry/Ellipse.php index f2d7f95c..17a6ee0b 100644 --- a/src/Geometry/Ellipse.php +++ b/src/Geometry/Ellipse.php @@ -17,12 +17,11 @@ class Ellipse implements DrawableInterface protected int $height, protected PointInterface $pivot = new Point() ) { - // } - public function size(int $width, int $height): self + public function pivot(): PointInterface { - return $this->setSize($width, $height); + return $this->pivot; } public function setSize(int $width, int $height): self @@ -44,12 +43,12 @@ class Ellipse implements DrawableInterface return $this; } - public function getWidth(): int + public function width(): int { return $this->width; } - public function getHeight(): int + public function height(): int { return $this->height; } diff --git a/src/Geometry/Line.php b/src/Geometry/Line.php index 7ef5a827..1de45eb8 100644 --- a/src/Geometry/Line.php +++ b/src/Geometry/Line.php @@ -16,10 +16,9 @@ class Line implements DrawableInterface protected Point $end, protected int $width = 1 ) { - // } - public function getWidth(): int + public function width(): int { return $this->width; } @@ -31,24 +30,12 @@ class Line implements DrawableInterface return $this; } - public function width(int $width): self - { - return $this->setWidth($width); - } - - public function color($color): self - { - $this->setBackgroundColor($color); - - return $this; - } - - public function getStart(): Point + public function start(): Point { return $this->start; } - public function getEnd(): Point + public function end(): Point { return $this->end; } @@ -62,16 +49,16 @@ class Line implements DrawableInterface public function from(int $x, int $y): self { - $this->getStart()->setX($x); - $this->getStart()->setY($y); + $this->start()->setX($x); + $this->start()->setY($y); return $this; } public function to(int $x, int $y): self { - $this->getEnd()->setX($x); - $this->getEnd()->setY($y); + $this->end()->setX($x); + $this->end()->setY($y); return $this; } diff --git a/src/Geometry/Pixel.php b/src/Geometry/Pixel.php index e1672fdd..eaa2326c 100644 --- a/src/Geometry/Pixel.php +++ b/src/Geometry/Pixel.php @@ -11,17 +11,16 @@ class Pixel extends Point protected int $x, protected int $y ) { - // } - public function withBackground(ColorInterface $background): self + public function setBackgroundColor(ColorInterface $background): self { $this->background = $background; return $this; } - public function background(): ColorInterface + public function backgroundColor(): ColorInterface { return $this->background; } diff --git a/src/Geometry/Point.php b/src/Geometry/Point.php index 7fc7ff3c..11b48c9e 100644 --- a/src/Geometry/Point.php +++ b/src/Geometry/Point.php @@ -6,9 +6,10 @@ use Intervention\Image\Interfaces\PointInterface; class Point implements PointInterface { - public function __construct(protected int $x = 0, protected int $y = 0) - { - // + public function __construct( + protected int $x = 0, + protected int $y = 0 + ) { } /** diff --git a/src/Geometry/Polygon.php b/src/Geometry/Polygon.php index fb4771f2..142f9d68 100644 --- a/src/Geometry/Polygon.php +++ b/src/Geometry/Polygon.php @@ -21,7 +21,6 @@ class Polygon implements IteratorAggregate, Countable, ArrayAccess, DrawableInte protected array $points = [], protected PointInterface $pivot = new Point() ) { - // } public function getIterator(): Traversable @@ -34,7 +33,7 @@ class Polygon implements IteratorAggregate, Countable, ArrayAccess, DrawableInte * * @return PointInterface */ - public function getPivot(): PointInterface + public function pivot(): PointInterface { return $this->pivot; } @@ -148,13 +147,6 @@ class Polygon implements IteratorAggregate, Countable, ArrayAccess, DrawableInte return $this; } - public function point(int $x, int $y): self - { - $this->addPoint(new Point($x, $y)); - - return $this; - } - /** * Calculate total horizontal span of polygon * @@ -162,7 +154,7 @@ class Polygon implements IteratorAggregate, Countable, ArrayAccess, DrawableInte */ public function width(): int { - return abs($this->getMostLeftPoint()->x() - $this->getMostRightPoint()->x()); + return abs($this->mostLeftPoint()->x() - $this->mostRightPoint()->x()); } /** @@ -172,7 +164,7 @@ class Polygon implements IteratorAggregate, Countable, ArrayAccess, DrawableInte */ public function height(): int { - return abs($this->getMostBottomPoint()->y() - $this->getMostTopPoint()->y()); + return abs($this->mostBottomPoint()->y() - $this->mostTopPoint()->y()); } /** @@ -180,7 +172,7 @@ class Polygon implements IteratorAggregate, Countable, ArrayAccess, DrawableInte * * @return Point */ - public function getMostLeftPoint(): Point + public function mostLeftPoint(): Point { $points = []; foreach ($this->points as $point) { @@ -202,7 +194,7 @@ class Polygon implements IteratorAggregate, Countable, ArrayAccess, DrawableInte * * @return Point */ - public function getMostRightPoint(): Point + public function mostRightPoint(): Point { $points = []; foreach ($this->points as $point) { @@ -224,7 +216,7 @@ class Polygon implements IteratorAggregate, Countable, ArrayAccess, DrawableInte * * @return Point */ - public function getMostTopPoint(): Point + public function mostTopPoint(): Point { $points = []; foreach ($this->points as $point) { @@ -246,7 +238,7 @@ class Polygon implements IteratorAggregate, Countable, ArrayAccess, DrawableInte * * @return Point */ - public function getMostBottomPoint(): Point + public function mostBottomPoint(): Point { $points = []; foreach ($this->points as $point) { @@ -264,15 +256,15 @@ class Polygon implements IteratorAggregate, Countable, ArrayAccess, DrawableInte } /** - * Create and return point in absolute center of the polygon + * Return point in absolute center of the polygon * * @return Point */ - public function getCenterPoint(): Point + public function centerPoint(): Point { return new Point( - $this->getMostRightPoint()->x() - (intval(round($this->width() / 2))), - $this->getMostTopPoint()->y() - (intval(round($this->height() / 2))) + $this->mostRightPoint()->x() - (intval(round($this->width() / 2))), + $this->mostTopPoint()->y() - (intval(round($this->height() / 2))) ); } @@ -287,16 +279,16 @@ class Polygon implements IteratorAggregate, Countable, ArrayAccess, DrawableInte switch (strtolower($position)) { case 'center': case 'middle': - $diff = ($this->getCenterPoint()->x() - $this->getPivot()->x()); + $diff = ($this->centerPoint()->x() - $this->pivot()->x()); break; case 'right': - $diff = ($this->getMostRightPoint()->x() - $this->getPivot()->x()); + $diff = ($this->mostRightPoint()->x() - $this->pivot()->x()); break; default: case 'left': - $diff = ($this->getMostLeftPoint()->x() - $this->getPivot()->x()); + $diff = ($this->mostLeftPoint()->x() - $this->pivot()->x()); break; } @@ -320,16 +312,16 @@ class Polygon implements IteratorAggregate, Countable, ArrayAccess, DrawableInte switch (strtolower($position)) { case 'center': case 'middle': - $diff = ($this->getCenterPoint()->y() - $this->getPivot()->y()); + $diff = ($this->centerPoint()->y() - $this->pivot()->y()); break; case 'top': - $diff = ($this->getMostTopPoint()->y() - $this->getPivot()->y()) - $this->height(); + $diff = ($this->mostTopPoint()->y() - $this->pivot()->y()) - $this->height(); break; default: case 'bottom': - $diff = ($this->getMostBottomPoint()->y() - $this->getPivot()->y()) + $this->height(); + $diff = ($this->mostBottomPoint()->y() - $this->pivot()->y()) + $this->height(); break; } @@ -356,10 +348,10 @@ class Polygon implements IteratorAggregate, Countable, ArrayAccess, DrawableInte foreach ($this->points as $point) { // translate point to pivot $point->setX( - intval($point->x() - $this->getPivot()->x()), + intval($point->x() - $this->pivot()->x()), ); $point->setY( - intval($point->y() - $this->getPivot()->y()), + intval($point->y() - $this->pivot()->y()), ); // rotate point @@ -368,10 +360,10 @@ class Polygon implements IteratorAggregate, Countable, ArrayAccess, DrawableInte // translate point back $point->setX( - intval($x + $this->getPivot()->x()), + intval($x + $this->pivot()->x()), ); $point->setY( - intval($y + $this->getPivot()->y()), + intval($y + $this->pivot()->y()), ); } diff --git a/src/Geometry/Rectangle.php b/src/Geometry/Rectangle.php index d32609a3..792303a8 100644 --- a/src/Geometry/Rectangle.php +++ b/src/Geometry/Rectangle.php @@ -3,17 +3,12 @@ namespace Intervention\Image\Geometry; use Intervention\Image\Geometry\Tools\RectangleResizer; -use Intervention\Image\Geometry\Traits\HasBackgroundColor; -use Intervention\Image\Geometry\Traits\HasBorder; use Intervention\Image\Interfaces\DrawableInterface; use Intervention\Image\Interfaces\PointInterface; use Intervention\Image\Interfaces\SizeInterface; class Rectangle extends Polygon implements SizeInterface, DrawableInterface { - use HasBorder; - use HasBackgroundColor; - public function __construct( int $width, int $height, @@ -37,14 +32,6 @@ class Rectangle extends Polygon implements SizeInterface, DrawableInterface return $this->setWidth($width)->setHeight($height); } - /** - * Alias of self::setSize() - */ - public function size(int $width, int $height): self - { - return $this->setSize($width, $height); - } - public function setWidth(int $width): self { $this[1]->setX($this[0]->x() + $width); @@ -235,38 +222,38 @@ class Rectangle extends Polygon implements SizeInterface, DrawableInterface return $this->points[2]; } - protected function getResizer(?int $width = null, ?int $height = null): RectangleResizer + protected function resizer(?int $width = null, ?int $height = null): RectangleResizer { return new RectangleResizer($width, $height); } public function resize(?int $width = null, ?int $height = null): SizeInterface { - return $this->getResizer($width, $height)->resize($this); + return $this->resizer($width, $height)->resize($this); } public function resizeDown(?int $width = null, ?int $height = null): SizeInterface { - return $this->getResizer($width, $height)->resizeDown($this); + return $this->resizer($width, $height)->resizeDown($this); } public function scale(?int $width = null, ?int $height = null): SizeInterface { - return $this->getResizer($width, $height)->scale($this); + return $this->resizer($width, $height)->scale($this); } public function scaleDown(?int $width = null, ?int $height = null): SizeInterface { - return $this->getResizer($width, $height)->scaleDown($this); + return $this->resizer($width, $height)->scaleDown($this); } public function cover(int $width, int $height): SizeInterface { - return $this->getResizer($width, $height)->cover($this); + return $this->resizer($width, $height)->cover($this); } public function contain(int $width, int $height): SizeInterface { - return $this->getResizer($width, $height)->contain($this); + return $this->resizer($width, $height)->contain($this); } } diff --git a/src/Geometry/Traits/HasBackgroundColor.php b/src/Geometry/Traits/HasBackgroundColor.php index 5987a516..4426ead0 100644 --- a/src/Geometry/Traits/HasBackgroundColor.php +++ b/src/Geometry/Traits/HasBackgroundColor.php @@ -4,27 +4,22 @@ namespace Intervention\Image\Geometry\Traits; trait HasBackgroundColor { - protected $backgroundColor = null; + protected mixed $backgroundColor = null; - public function background($color): self - { - return $this->setBackgroundColor($color); - } - - public function setBackgroundColor($color): self + public function setBackgroundColor(mixed $color): self { $this->backgroundColor = $color; return $this; } - public function getBackgroundColor() + public function backgroundColor(): mixed { return $this->backgroundColor; } public function hasBackgroundColor(): bool { - return !is_null($this->backgroundColor); + return !empty($this->backgroundColor); } } diff --git a/src/Geometry/Traits/HasBorder.php b/src/Geometry/Traits/HasBorder.php index f9df9900..67142f5a 100644 --- a/src/Geometry/Traits/HasBorder.php +++ b/src/Geometry/Traits/HasBorder.php @@ -4,10 +4,10 @@ namespace Intervention\Image\Geometry\Traits; trait HasBorder { - protected $borderColor = null; - protected $borderSize = 0; + protected mixed $borderColor = null; + protected int $borderSize = 0; - public function border($color, int $size = 1): self + public function setBorder(mixed $color, int $size = 1): self { return $this->setBorderSize($size)->setBorderColor($color); } @@ -19,19 +19,19 @@ trait HasBorder return $this; } - public function getBorderSize(): int + public function borderSize(): int { return $this->borderSize; } - public function setBorderColor($color): self + public function setBorderColor(mixed $color): self { $this->borderColor = $color; return $this; } - public function getBorderColor() + public function borderColor(): mixed { return $this->borderColor; } diff --git a/src/Image.php b/src/Image.php new file mode 100644 index 00000000..0edb8ac5 --- /dev/null +++ b/src/Image.php @@ -0,0 +1,90 @@ +driver; + } + + public function core(): CoreInterface + { + return $this->core; + } + + public function width(): int + { + return $this->core->width(); + } + + public function height(): int + { + return $this->core->height(); + } + + public function size(): SizeInterface + { + return new Rectangle($this->width(), $this->height()); + } + + public function count(): int + { + return $this->core->count(); + } + + public function getIterator(): Traversable + { + return $this->core; + } + + public function isAnimated(): bool + { + return $this->count() > 1; + } + + public function loops(): int + { + return $this->core->loops(); + } + + public function colorspace(): ColorspaceInterface + { + return $this->core->colorspace(); + } + + public function exif(?string $query = null): mixed + { + return is_null($query) ? $this->exif : $this->exif->get($query); + } + + public function modify(ModifierInterface $modifier): ImageInterface + { + return $this->driver->resolve($modifier)->apply($this); + } + + public function encode(EncoderInterface $encoder): EncodedImage + { + return $this->driver->resolve($encoder)->encode($this); + } +} diff --git a/src/ImageManager.php b/src/ImageManager.php index f1e30a23..ae3ec17a 100644 --- a/src/ImageManager.php +++ b/src/ImageManager.php @@ -2,124 +2,51 @@ namespace Intervention\Image; -use Intervention\Image\Exceptions\ConfigurationException; +use Intervention\Image\Interfaces\DriverInterface; use Intervention\Image\Interfaces\ImageInterface; +use Intervention\Image\Drivers\Gd\Driver as GdDriver; +use Intervention\Image\Drivers\Imagick\Driver as ImagickDriver; -class ImageManager +final class ImageManager { - /** - * Create new ImageManager instance - * - * @param string $driver - * @return void - * @throws ConfigurationException - */ - public function __construct(protected string $driver = 'gd') + protected DriverInterface $driver; + + public function __construct(string|DriverInterface $driver) { - if (!$this->driverExists()) { - throw new ConfigurationException('Driver ' . $driver . ' is not available.'); - } + $this->driver = $this->resolveDriver($driver); } - /** - * Static constructor to create ImageManager with given driver - * - * @param string $driver - * @return ImageManager - */ - public static function withDriver(string $driver): self + public static function withDriver(string|DriverInterface $driver): self { - return new self($driver); + return new self(self::resolveDriver($driver)); } - /** - * Static helper to create ImageManager with GD driver - * - * @return ImageManager - */ public static function gd(): self { - return new self('gd'); + return self::withDriver(GdDriver::class); } - /** - * Static constructor to create ImageManager with Imagick driver - * - * @return ImageManager - */ public static function imagick(): self { - return new self('imagick'); + return self::withDriver(ImagickDriver::class); } - /** - * Create new image instance from scratch - * - * @param int $width - * @param int $height - * @return ImageInterface - */ public function create(int $width, int $height): ImageInterface { - return $this->resolveDriverClass('Factory')->newImage($width, $height); + return $this->driver->createImage($width, $height); } - /** - * Create new animated image from sources - * - * @param callable $callback - * @return ImageInterface - */ - public function animate(callable $callback): ImageInterface + public function read(mixed $input): ImageInterface { - return $this->resolveDriverClass('Factory')->newAnimation($callback); + return $this->driver->handleInput($input); } - /** - * Create new image instance from source - * - * @param mixed $source - * @return ImageInterface - */ - public function read($source): ImageInterface + private static function resolveDriver(string|DriverInterface $driver): DriverInterface { - return $this->resolveDriverClass('InputHandler')->handle($source); - } + if (is_object($driver)) { + return $driver; + } - /** - * Resolve given classname with configured driver - * - * @return object - */ - private function resolveDriverClass(string $classname): object - { - $classname = $this->driverClassname($classname); - - return new $classname(); - } - - /** - * Build full namespaced classname of given class for configured driver - * - * @param string $classname - * @return string - */ - private function driverClassname(string $classname): string - { - return sprintf( - "Intervention\Image\Drivers\%s\%s", - ucfirst($this->driver), - $classname - ); - } - - /** - * Determine if configured driver exists - * - * @return bool - */ - private function driverExists(): bool - { - return class_exists($this->driverClassname('Image')); + return new $driver(); } } diff --git a/src/Interfaces/CollectionInterface.php b/src/Interfaces/CollectionInterface.php index f42769a3..06d5bca7 100644 --- a/src/Interfaces/CollectionInterface.php +++ b/src/Interfaces/CollectionInterface.php @@ -6,8 +6,10 @@ use Traversable; interface CollectionInterface extends Traversable { + public function has(int|string $key): bool; public function push($item): CollectionInterface; public function get(int|string $key, $default = null); + public function getAtPosition(int $key = 0, $default = null); public function first(); public function last(); public function count(): int; diff --git a/src/Interfaces/ColorProcessorInterface.php b/src/Interfaces/ColorProcessorInterface.php new file mode 100644 index 00000000..3362e385 --- /dev/null +++ b/src/Interfaces/ColorProcessorInterface.php @@ -0,0 +1,8 @@ +modify($this); + } +} diff --git a/src/Modifiers/BlurModifier.php b/src/Modifiers/BlurModifier.php new file mode 100644 index 00000000..7801902d --- /dev/null +++ b/src/Modifiers/BlurModifier.php @@ -0,0 +1,10 @@ +target)) { + return $this->target; + } + + if (in_array($this->target, ['rgb', 'RGB', RgbColorspace::class])) { + return new RgbColorspace(); + } + + if (in_array($this->target, ['cmyk', 'CMYK', CmykColorspace::class])) { + return new CmykColorspace(); + } + + throw new NotSupportedException('Given colorspace is not supported.'); + } +} diff --git a/src/Modifiers/ContrastModifier.php b/src/Modifiers/ContrastModifier.php new file mode 100644 index 00000000..5260fa4b --- /dev/null +++ b/src/Modifiers/ContrastModifier.php @@ -0,0 +1,10 @@ +width, $this->height); + $crop->align($this->position); + + return $crop->alignPivotTo( + $image->size(), + $this->position + ); + } +} diff --git a/src/Modifiers/DrawEllipseModifier.php b/src/Modifiers/DrawEllipseModifier.php new file mode 100644 index 00000000..5448d860 --- /dev/null +++ b/src/Modifiers/DrawEllipseModifier.php @@ -0,0 +1,12 @@ +position); + } +} diff --git a/src/Modifiers/FitDownModifier.php b/src/Modifiers/FitDownModifier.php new file mode 100644 index 00000000..6a792ad2 --- /dev/null +++ b/src/Modifiers/FitDownModifier.php @@ -0,0 +1,7 @@ +size(); + + $crop = new Rectangle($this->width, $this->height); + $crop = $crop->contain( + $imagesize->width(), + $imagesize->height() + )->alignPivotTo($imagesize, $this->position); + + return $crop; + } + + public function getResizeSize(SizeInterface $size): SizeInterface + { + return $size->scale($this->width, $this->height); + } +} diff --git a/src/Modifiers/FlipModifier.php b/src/Modifiers/FlipModifier.php new file mode 100644 index 00000000..8251d91b --- /dev/null +++ b/src/Modifiers/FlipModifier.php @@ -0,0 +1,7 @@ +getResizeSize($image); + + return $image->size() + ->contain($resize->width(), $resize->height()) + ->alignPivotTo($resize, $this->position); + } + + public function getResizeSize(ImageInterface $image): SizeInterface + { + return (new Rectangle($this->width, $this->height)) + ->resizeDown($image->width(), $image->height()); + } +} diff --git a/src/Modifiers/PadModifier.php b/src/Modifiers/PadModifier.php new file mode 100644 index 00000000..25ef5571 --- /dev/null +++ b/src/Modifiers/PadModifier.php @@ -0,0 +1,30 @@ +size() + ->contain($this->width, $this->height) + ->alignPivotTo($this->getResizeSize($image), $this->position); + } + + public function getResizeSize(ImageInterface $image): SizeInterface + { + return new Rectangle($this->width, $this->height); + } +} diff --git a/src/Modifiers/PixelateModifier.php b/src/Modifiers/PixelateModifier.php new file mode 100644 index 00000000..3d706fd4 --- /dev/null +++ b/src/Modifiers/PixelateModifier.php @@ -0,0 +1,10 @@ +size()->movePivot( + $this->position, + $this->offset_x, + $this->offset_y + ); + + $watermark_size = $watermark->size()->movePivot( + $this->position + ); + + return $image_size->relativePositionTo($watermark_size); + } +} diff --git a/src/Modifiers/ProfileModifier.php b/src/Modifiers/ProfileModifier.php new file mode 100644 index 00000000..de21a5d2 --- /dev/null +++ b/src/Modifiers/ProfileModifier.php @@ -0,0 +1,12 @@ +core()->frame($position); + } + + if (preg_match("/^(?P[0-9]{1,3})%$/", $position, $matches) != 1) { + throw new InputException( + 'Position must be either integer or a percent value as string.' + ); + } + + $total = count($image); + $position = intval(round($total / 100 * intval($matches['percent']))); + $position = $position == $total ? $position - 1 : $position; + + return $image->core()->frame($position); + } +} diff --git a/src/Modifiers/ResizeDownModifier.php b/src/Modifiers/ResizeDownModifier.php new file mode 100644 index 00000000..30ff067a --- /dev/null +++ b/src/Modifiers/ResizeDownModifier.php @@ -0,0 +1,7 @@ +angle, 360); + } +} diff --git a/src/Modifiers/ScaleDownModifier.php b/src/Modifiers/ScaleDownModifier.php new file mode 100644 index 00000000..34367f30 --- /dev/null +++ b/src/Modifiers/ScaleDownModifier.php @@ -0,0 +1,7 @@ +font; - } - - protected function getPosition(): Point - { - return $this->position; } /** @@ -39,8 +24,8 @@ abstract class AbstractTextWriter implements ModifierInterface public function getAlignedTextBlock(): TextBlock { $lines = new TextBlock($this->text); - $position = $this->getPosition(); - $font = $this->getFont(); + $position = $this->position; + $font = $this->font; $boundingBox = $lines->getBoundingBox($font, $position); $pivot = $boundingBox->last(); diff --git a/tests/Geometry/PixelTest.php b/tests/Geometry/PixelTest.php index 6719682a..f034abdf 100644 --- a/tests/Geometry/PixelTest.php +++ b/tests/Geometry/PixelTest.php @@ -16,8 +16,8 @@ class PixelTest extends TestCase { $color = Mockery::mock(ColorInterface::class); $pixel = new Pixel($color, 10, 12); - $result = $pixel->withBackground($color); - $this->assertInstanceOf(ColorInterface::class, $pixel->background()); + $result = $pixel->setBackgroundColor($color); + $this->assertInstanceOf(ColorInterface::class, $pixel->backgroundColor()); $this->assertInstanceOf(Pixel::class, $result); } } diff --git a/tests/Geometry/PolygonTest.php b/tests/Geometry/PolygonTest.php index 7ba38260..c394b44c 100644 --- a/tests/Geometry/PolygonTest.php +++ b/tests/Geometry/PolygonTest.php @@ -48,7 +48,7 @@ class PolygonTest extends TestCase new Point(0, -20), ]); - $result = $poly->getCenterPoint(); + $result = $poly->centerPoint(); $this->assertEquals(10, $result->x()); $this->assertEquals(-10, $result->y()); @@ -59,7 +59,7 @@ class PolygonTest extends TestCase new Point(0, -200), ], new Point(0, 0)); - $result = $poly->getCenterPoint(); + $result = $poly->centerPoint(); $this->assertEquals(150, $result->x()); $this->assertEquals(-100, $result->y()); } @@ -122,7 +122,7 @@ class PolygonTest extends TestCase public function testGetPivotPoint(): void { $poly = new Polygon(); - $this->assertInstanceOf(Point::class, $poly->getPivot()); + $this->assertInstanceOf(Point::class, $poly->pivot()); } public function testGetMostLeftPoint(): void @@ -134,7 +134,7 @@ class PolygonTest extends TestCase new Point(-32, -200), ], new Point(0, 0)); - $result = $poly->getMostLeftPoint(); + $result = $poly->mostLeftPoint(); $this->assertEquals(-32, $result->x()); $this->assertEquals(-200, $result->y()); } @@ -148,7 +148,7 @@ class PolygonTest extends TestCase new Point(-32, -200), ], new Point(0, 0)); - $result = $poly->getMostRightPoint(); + $result = $poly->mostRightPoint(); $this->assertEquals(350, $result->x()); $this->assertEquals(0, $result->y()); } @@ -162,7 +162,7 @@ class PolygonTest extends TestCase new Point(-32, 200), ], new Point(0, 0)); - $result = $poly->getMostTopPoint(); + $result = $poly->mostTopPoint(); $this->assertEquals(-32, $result->x()); $this->assertEquals(200, $result->y()); } @@ -176,7 +176,7 @@ class PolygonTest extends TestCase new Point(-32, 200), ], new Point(0, 0)); - $result = $poly->getMostBottomPoint(); + $result = $poly->mostBottomPoint(); $this->assertEquals(300, $result->x()); $this->assertEquals(-200, $result->y()); } diff --git a/tests/Typography/TextBlockTest.php b/tests/Typography/TextBlockTest.php index 70fa9829..8342b160 100644 --- a/tests/Typography/TextBlockTest.php +++ b/tests/Typography/TextBlockTest.php @@ -73,7 +73,7 @@ class TextBlockTest extends TestCase $box = $block->getBoundingBox($font, new Point(10, 15)); $this->assertEquals(300, $box->width()); $this->assertEquals(82, $box->height()); - $this->assertEquals(10, $box->getPivot()->x()); - $this->assertEquals(15, $box->getPivot()->y()); + $this->assertEquals(10, $box->pivot()->x()); + $this->assertEquals(15, $box->pivot()->y()); } }