diff --git a/src/Drivers/Abstract/AbstractImage.php b/src/Drivers/Abstract/AbstractImage.php deleted file mode 100644 index 5d8fbc89..00000000 --- a/src/Drivers/Abstract/AbstractImage.php +++ /dev/null @@ -1,406 +0,0 @@ -width(), $this->height()); - } - - public function modify(ModifierInterface $modifier): ImageInterface - { - return $modifier->apply($this); - } - - public function encode(EncoderInterface $encoder): EncodedImage - { - return $encoder->encode($this); - } - - public function toJpeg(int $quality = 75): EncodedImage - { - return $this->encode( - $this->resolveDriverClass('Encoders\JpegEncoder', $quality) - ); - } - - public function toJpg(int $quality = 75): EncodedImage - { - return $this->toJpeg($quality); - } - - public function toWebp(int $quality = 75): EncodedImage - { - return $this->encode( - $this->resolveDriverClass('Encoders\WebpEncoder', $quality) - ); - } - - public function toGif(int $color_limit = 0): EncodedImage - { - return $this->encode( - $this->resolveDriverClass('Encoders\GifEncoder', $color_limit) - ); - } - - public function toPng(int $color_limit = 0): EncodedImage - { - return $this->encode( - $this->resolveDriverClass('Encoders\PngEncoder', $color_limit) - ); - } - - public function toBitmap(int $color_limit = 0): EncodedImage - { - return $this->encode( - $this->resolveDriverClass('Encoders\BmpEncoder', $color_limit) - ); - } - - public function toBmp(int $color_limit = 0): EncodedImage - { - return $this->toBitmap($color_limit); - } - - public function toAvif(int $quality = 75): EncodedImage - { - return $this->encode( - $this->resolveDriverClass('Encoders\AvifEncoder', $quality) - ); - } - - public function greyscale(): ImageInterface - { - return $this->modify( - $this->resolveDriverClass('Modifiers\GreyscaleModifier') - ); - } - - public function invert(): ImageInterface - { - return $this->modify( - $this->resolveDriverClass('Modifiers\InvertModifier') - ); - } - - public function brightness(int $level): ImageInterface - { - return $this->modify( - $this->resolveDriverClass('Modifiers\BrightnessModifier', $level) - ); - } - - public function contrast(int $level): ImageInterface - { - return $this->modify( - $this->resolveDriverClass('Modifiers\ContrastModifier', $level) - ); - } - - public function gamma(float $gamma): ImageInterface - { - return $this->modify( - $this->resolveDriverClass('Modifiers\GammaModifier', $gamma) - ); - } - - public function colorize(int $red = 0, int $green = 0, int $blue = 0): ImageInterface - { - return $this->modify( - $this->resolveDriverClass('Modifiers\ColorizeModifier', $red, $green, $blue) - ); - } - - public function blur(int $amount = 5): ImageInterface - { - return $this->modify( - $this->resolveDriverClass('Modifiers\BlurModifier', $amount) - ); - } - - public function rotate(float $angle, $background = 'ffffff'): ImageInterface - { - return $this->modify( - $this->resolveDriverClass('Modifiers\RotateModifier', $angle, $background) - ); - } - - /** - * Creates a vertical mirror image - * - * @return ImageInterface - */ - public function flip(): ImageInterface - { - return $this->modify( - $this->resolveDriverClass('Modifiers\FlipModifier') - ); - } - - /** - * Creates a horizontal mirror image - * - * @return ImageInterface - */ - public function flop(): ImageInterface - { - return $this->modify( - $this->resolveDriverClass('Modifiers\FlopModifier') - ); - } - - public function place($element, string $position = 'top-left', int $offset_x = 0, int $offset_y = 0): ImageInterface - { - return $this->modify( - $this->resolveDriverClass( - 'Modifiers\PlaceModifier', - $element, - $position, - $offset_x, - $offset_y - ) - ); - } - - public function fill($color, ?int $x = null, ?int $y = null): ImageInterface - { - $color = $this->handleInput($color); - $position = (is_null($x) && is_null($y)) ? null : new Point($x, $y); - - return $this->modify( - $this->resolveDriverClass( - 'Modifiers\FillModifier', - $color, - $position - ) - ); - } - - public function pixelate(int $size): ImageInterface - { - return $this->modify( - $this->resolveDriverClass('Modifiers\PixelateModifier', $size) - ); - } - - public function sharpen(int $amount = 10): ImageInterface - { - return $this->modify( - $this->resolveDriverClass('Modifiers\SharpenModifier', $amount) - ); - } - - /** - * {@inheritdoc} - * - * @see ImageInterface::pickColors() - */ - public function pickColors(int $x, int $y): CollectionInterface - { - $colors = new Collection(); - foreach ($this as $key => $frame) { - $colors->push($this->pickColor($x, $y, $key)); - } - - return $colors; - } - - public function text(string $text, int $x, int $y, ?callable $init = null): ImageInterface - { - $font = $this->maybeRunCallback($init, $this->resolveDriverClass('Font')); - - $modifier = $this->resolveDriverClass('Modifiers\TextWriter', new Point($x, $y), $font, $text); - - return $this->modify($modifier); - } - - public function drawPixel(int $x, int $y, $color = null): ImageInterface - { - return $this->modify( - $this->resolveDriverClass('Modifiers\DrawPixelModifier', new Point($x, $y), $color) - ); - } - - public function drawRectangle(int $x, int $y, ?callable $init = null): ImageInterface - { - $rectangle = $this->maybeRunCallback($init, new Rectangle(0, 0)); - $modifier = $this->resolveDriverClass('Modifiers\DrawRectangleModifier', new Point($x, $y), $rectangle); - - return $this->modify($modifier); - } - - public function drawEllipse(int $x, int $y, ?callable $init = null): ImageInterface - { - $ellipse = $this->maybeRunCallback($init, new Ellipse(0, 0)); - $modifier = $this->resolveDriverClass('Modifiers\DrawEllipseModifier', new Point($x, $y), $ellipse); - - return $this->modify($modifier); - } - - public function drawCircle(int $x, int $y, ?callable $init = null): ImageInterface - { - $circle = $this->maybeRunCallback($init, new Circle(0)); - $modifier = $this->resolveDriverClass('Modifiers\DrawEllipseModifier', new Point($x, $y), $circle); - - return $this->modify($modifier); - } - - public function drawLine(callable $init = null): ImageInterface - { - $line = $this->maybeRunCallback($init, new Line(new Point(), new Point())); - $modifier = $this->resolveDriverClass('Modifiers\DrawLineModifier', $line->getStart(), $line); - - return $this->modify($modifier); - } - - public function drawPolygon(callable $init = null): ImageInterface - { - $polygon = $this->maybeRunCallback($init, new Polygon()); - $modifier = $this->resolveDriverClass('Modifiers\DrawPolygonModifier', $polygon); - - return $this->modify($modifier); - } - - public function resize(?int $width = null, ?int $height = null): ImageInterface - { - return $this->modify( - $this->resolveDriverClass('Modifiers\ResizeModifier', $width, $height) - ); - } - - public function resizeDown(?int $width = null, ?int $height = null): ImageInterface - { - return $this->modify( - $this->resolveDriverClass('Modifiers\ResizeDownModifier', $width, $height) - ); - } - - public function scale(?int $width = null, ?int $height = null): ImageInterface - { - return $this->modify( - $this->resolveDriverClass('Modifiers\ScaleModifier', $width, $height) - ); - } - - public function scaleDown(?int $width = null, ?int $height = null): ImageInterface - { - return $this->modify( - $this->resolveDriverClass('Modifiers\ScaleDownModifier', $width, $height) - ); - } - - public function fit(int $width, int $height, string $position = 'center'): ImageInterface - { - return $this->modify( - $this->resolveDriverClass('Modifiers\FitModifier', $width, $height, $position) - ); - } - - public function fitDown(int $width, int $height, string $position = 'center'): ImageInterface - { - return $this->modify( - $this->resolveDriverClass('Modifiers\FitDownModifier', $width, $height, $position) - ); - } - - public function pad(int $width, int $height, $background = 'ffffff', string $position = 'center'): ImageInterface - { - return $this->modify( - $this->resolveDriverClass('Modifiers\PadModifier', $width, $height, $background, $position) - ); - } - - public function padDown( - int $width, - int $height, - $background = 'ffffff', - string $position = 'center' - ): ImageInterface { - return $this->modify( - $this->resolveDriverClass('Modifiers\PadDownModifier', $width, $height, $background, $position) - ); - } - - public function crop( - int $width, - int $height, - int $offset_x = 0, - int $offset_y = 0, - string $position = 'top-left' - ): ImageInterface { - return $this->modify( - $this->resolveDriverClass('Modifiers\CropModifier', $width, $height, $offset_x, $offset_y, $position) - ); - } - - public function removeAnimation(int|string $position = 0): ImageInterface - { - return $this->modify( - $this->resolveDriverClass('Modifiers\RemoveAnimationModifier', $position) - ); - } - - public function setExif(array $data): ImageInterface - { - $this->exif = new Collection($data); - - return $this; - } - - public function exif(?string $query = null): mixed - { - if (!isset($this->exif)) { - return new Collection(); - } - - return is_null($query) ? $this->exif : $this->exif->get($query); - } - - public function setResolution(float $x, float $y): ImageInterface - { - return $this->modify( - $this->resolveDriverClass('Modifiers\ResolutionModifier', $x, $y) - ); - } - - public function destroy(): void - { - $this->modify( - $this->resolveDriverClass('Modifiers\DestroyModifier') - ); - } -} diff --git a/src/Drivers/Abstract/AbstractInputHandler.php b/src/Drivers/Abstract/AbstractInputHandler.php deleted file mode 100644 index 62a127a9..00000000 --- a/src/Drivers/Abstract/AbstractInputHandler.php +++ /dev/null @@ -1,60 +0,0 @@ -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/Abstract/Decoders/AbstractDecoder.php b/src/Drivers/Abstract/Decoders/AbstractDecoder.php deleted file mode 100644 index a7182d13..00000000 --- a/src/Drivers/Abstract/Decoders/AbstractDecoder.php +++ /dev/null @@ -1,153 +0,0 @@ -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): array - { - 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 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/Abstract/Modifiers/AbstractDrawModifier.php b/src/Drivers/Abstract/Modifiers/AbstractDrawModifier.php deleted file mode 100644 index ea1c09a2..00000000 --- a/src/Drivers/Abstract/Modifiers/AbstractDrawModifier.php +++ /dev/null @@ -1,92 +0,0 @@ -drawable; - } - - protected function getBackgroundColor(): ColorInterface - { - try { - $color = $this->handleInput($this->drawable->getBackgroundColor()); - } catch (DecoderException $e) { - return $this->handleInput('transparent'); - } - - return $color; - } - - protected function getBorderColor(): ColorInterface - { - try { - $color = $this->handleInput($this->drawable->getBorderColor()); - } catch (DecoderException $e) { - return $this->handleInput('transparent'); - } - - return $color; - } - - public function polygon(): Polygon - { - if (!is_a($this->drawable(), Polygon::class)) { - throw new GeometryException( - 'Shape mismatch. Excepted Polygon::class, found ' . get_class($this->drawable()) - ); - } - - return $this->drawable(); - } - - public function ellipse(): Ellipse - { - if (!is_a($this->drawable(), Ellipse::class)) { - throw new GeometryException( - 'Shape mismatch. Excepted Ellipse::class, found ' . get_class($this->drawable()) - ); - } - - return $this->drawable(); - } - - public function line(): Line - { - if (!is_a($this->drawable(), Line::class)) { - throw new GeometryException( - 'Shape mismatch. Excepted Line::class, found ' . get_class($this->drawable()) - ); - } - - return $this->drawable(); - } - - public function rectangle(): Rectangle - { - if (!is_a($this->drawable(), Rectangle::class)) { - throw new GeometryException( - 'Shape mismatch. Excepted Rectangle::class, found ' . get_class($this->drawable()) - ); - } - - return $this->drawable(); - } -} diff --git a/src/Drivers/Abstract/Modifiers/AbstractFitModifier.php b/src/Drivers/Abstract/Modifiers/AbstractFitModifier.php deleted file mode 100644 index 988b955c..00000000 --- a/src/Drivers/Abstract/Modifiers/AbstractFitModifier.php +++ /dev/null @@ -1,35 +0,0 @@ -size(); - - $crop = new Rectangle($this->width, $this->height); - $crop = $crop->contain( - $imagesize->width(), - $imagesize->height() - )->alignPivotTo($imagesize, $this->position); - - return $crop; - } - - protected function getResizeSize(SizeInterface $size): SizeInterface - { - return $size->scale($this->width, $this->height); - } -} diff --git a/src/Drivers/Abstract/Modifiers/AbstractPadModifier.php b/src/Drivers/Abstract/Modifiers/AbstractPadModifier.php deleted file mode 100644 index c5585f89..00000000 --- a/src/Drivers/Abstract/Modifiers/AbstractPadModifier.php +++ /dev/null @@ -1,34 +0,0 @@ -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/Drivers/Abstract/Modifiers/AbstractRemoveAnimationModifier.php b/src/Drivers/Abstract/Modifiers/AbstractRemoveAnimationModifier.php deleted file mode 100644 index 68d3455f..00000000 --- a/src/Drivers/Abstract/Modifiers/AbstractRemoveAnimationModifier.php +++ /dev/null @@ -1,29 +0,0 @@ -frame($position); - } - - if (preg_match("/^(?P[0-9]{1,3})%$/", $position, $matches) != 1) { - throw new InputException( - 'Input value of Image::removeAnimation() 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->frame($position); - } -} diff --git a/src/Drivers/Abstract/Modifiers/AbstractRotateModifier.php b/src/Drivers/Abstract/Modifiers/AbstractRotateModifier.php deleted file mode 100644 index 123e7c70..00000000 --- a/src/Drivers/Abstract/Modifiers/AbstractRotateModifier.php +++ /dev/null @@ -1,40 +0,0 @@ -angle, 360); - } - - protected function backgroundColor(): ColorInterface - { - try { - return $this->handleInput($this->background); - } catch (DecoderException $e) { - throw new TypeException("rotate(): Argument #2 must be a color value."); - } - } -} diff --git a/src/Drivers/Gd/Factory.php b/src/Drivers/Gd/Factory.php deleted file mode 100644 index f429eb6b..00000000 --- a/src/Drivers/Gd/Factory.php +++ /dev/null @@ -1,91 +0,0 @@ -newCore($width, $height)) - ]) - ); - } - - /** - * {@inheritdoc} - * - * @see FactoryInterface::newAnimation() - */ - public function newAnimation(callable $callback): ImageInterface - { - $frames = new Collection(); - - $animation = new class ($frames) extends Factory - { - public function __construct(public Collection $frames) - { - // - } - - public function add($source, float $delay = 1): self - { - $this->frames->push( - $this->handleInput($source) - ->frame() - ->setDelay($delay) - ); - - return $this; - } - }; - - $callback($animation); - - return new Image($frames); - } - - /** - * {@inheritdoc} - * - * @see FactoryInterface::newCore() - */ - public function newCore(int $width, int $height, ?ColorInterface $background = null) - { - $core = imagecreatetruecolor($width, $height); - - imagesavealpha($core, true); - - $color = match (is_null($background)) { - true => imagecolorallocatealpha($core, 255, 0, 255, 127), - default => $this->allocateColor($core, $background), - }; - - imagealphablending($core, false); - imagefill($core, 0, 0, $color); - if ($background && $background->channel(Alpha::class)->value() == 0) { - imagecolortransparent($core, $color); - } - - return $core; - } -} diff --git a/src/Drivers/Gd/Image.php b/src/Drivers/Gd/Image.php deleted file mode 100644 index 2f2a56ba..00000000 --- a/src/Drivers/Gd/Image.php +++ /dev/null @@ -1,177 +0,0 @@ -frames; - } - - public function setFrames(Collection $frames): ImageInterface - { - $this->frames = $frames; - - return $this; - } - - public function getIterator(): Traversable - { - return $this->frames; - } - - public function count(): int - { - return $this->frames->count(); - } - - public function isAnimated(): bool - { - return $this->count() > 1; - } - - public function loops(): int - { - return $this->loops; - } - - public function setLoops(int $count): self - { - $this->loops = $count; - - return $this; - } - - public function frame(int $position = 0): FrameInterface - { - if ($frame = $this->frames->get($position)) { - return $frame; - } - - throw new AnimationException('Frame #' . $position . ' is not be found in the image.'); - } - - public function addFrame(FrameInterface $frame): ImageInterface - { - $this->frames->push($frame); - - return $this; - } - - public function width(): int - { - return imagesx($this->frame()->core()); - } - - public function height(): int - { - return imagesy($this->frame()->core()); - } - - /** - * {@inheritdoc} - * - * @see ImageInterface::resolution() - */ - public function resolution(): ResolutionInterface - { - return new Resolution(...imageresolution($this->frame()->core())); - } - - public function pickColor(int $x, int $y, int $frame_key = 0): ColorInterface - { - $gd = $this->frame($frame_key)->core(); - $index = @imagecolorat($gd, $x, $y); - - if ($index === false) { - throw new GeometryException('The specified position is not in the valid image area.'); - } - - $colors = imagecolorsforindex($gd, $index); - - return $this->arrayToColor($colors); - } - - /** - * {@inheritdoc} - * - * @see ImageInterface::getColorspace() - */ - public function colorspace(): ColorspaceInterface - { - return new RgbColorspace(); - } - - /** - * {@inheritdoc} - * - * @see ImageInterface::setColorspace() - */ - public function setColorspace(string|ColorspaceInterface $target): ImageInterface - { - if (is_string($target) && !in_array($target, ['rgb', RgbColorspace::class])) { - throw new NotSupportedException('Only RGB colorspace is supported with GD driver.'); - } - - if (is_object($target) && !is_a($target, RgbColorspace::class)) { - throw new NotSupportedException('Only RGB colorspace is supported with GD driver.'); - } - - return $this; - } - - /** - * {@inheritdoc} - * - * @see ImageInterface::setProfile() - */ - public function setProfile(string|ProfileInterface $input): ImageInterface - { - throw new NotSupportedException('Color profiles are not supported by GD driver.'); - } - - /** - * {@inheritdoc} - * - * @see ImageInterface::profile() - */ - public function profile(): ProfileInterface - { - throw new NotSupportedException('Color profiles are not supported by GD driver.'); - } - - /** - * {@inheritdoc} - * - * @see ImageInterface::removeProfile() - */ - public function removeProfile(): ImageInterface - { - throw new NotSupportedException('Color profiles are not supported by GD driver.'); - } -} diff --git a/src/Drivers/Gd/Traits/CanHandleColors.php b/src/Drivers/Gd/Traits/CanHandleColors.php deleted file mode 100644 index 3159f6ec..00000000 --- a/src/Drivers/Gd/Traits/CanHandleColors.php +++ /dev/null @@ -1,110 +0,0 @@ -channel(Red::class)->value(), - $color->channel(Green::class)->value(), - $color->channel(Blue::class)->value(), - $this->convertRange($color->channel(Alpha::class)->value(), 0, 255, 127, 0) - ); - } - - /** - * Transforms array result from imagecolorsforindex() to Color object - * - * @param array $values - * @return Color - */ - protected function arrayToColor(array $values): Color - { - list($r, $g, $b, $a) = array_values($values); - - // convert gd apha integer to intervention alpha integer - // ([opaque]0-127[transparent]) to ([opaque]255-0[transparent]) - $a = (int) static::convertRange($a, 127, 0, 0, 255); - - return new Color($r, $g, $b, $a); - } - - /** - * Transforms GD Library integer color value to RGB color object - * - * @param int $value - * @return Color - */ - public function integerToColor(int $value): Color - { - $a = ($value >> 24) & 0xFF; - $r = ($value >> 16) & 0xFF; - $g = ($value >> 8) & 0xFF; - $b = $value & 0xFF; - - // convert gd apha integer to intervention alpha integer - // ([opaque]0-127[transparent]) to ([opaque]255-0[transparent]) - $a = (int) static::convertRange($a, 127, 0, 0, 255); - - return new Color($r, $g, $b, $a); - } - - /** - * Transforms given color to the corresponding GD Library integer value - * - * @param Color $color - * @return int - */ - public function colorToInteger(Color $color): int - { - $r = $color->red()->value(); - $g = $color->green()->value(); - $b = $color->blue()->value(); - $a = $color->alpha()->value(); - - // convert alpha value to gd alpha - // ([opaque]255-0[transparent]) to ([opaque]0-127[transparent]) - $a = (int) static::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 static 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/Imagick/Factory.php b/src/Drivers/Imagick/Factory.php deleted file mode 100644 index 2f5d777d..00000000 --- a/src/Drivers/Imagick/Factory.php +++ /dev/null @@ -1,89 +0,0 @@ -newCore($width, $height)); - } - - /** - * {@inheritdoc} - * - * @see FactoryInterface::newAnimation() - */ - public function newAnimation(callable $callback): ImageInterface - { - $imagick = new Imagick(); - $imagick->setFormat('gif'); - - $animation = new class ($imagick) extends Factory - { - public function __construct(public Imagick $imagick) - { - // - } - - public function add($source, float $delay = 1): self - { - $imagick = $this->failIfNotClass( - $this->handleInput($source), - Image::class, - )->getImagick(); - $imagick->setImageDelay($delay * 100); - - $this->imagick->addImage($imagick); - - return $this; - } - }; - - $callback($animation); - - return new Image($animation->imagick); - } - - /** - * {@inheritdoc} - * - * @see FactoryInterface::newCore() - */ - public function newCore(int $width, int $height, ?ColorInterface $background = null) - { - $pixel = $background ? $this->colorToPixel( - $background, - new Colorspace() - ) : new ImagickPixel('rgba(0, 0, 0, 0)'); - - $imagick = new Imagick(); - $imagick->newImage($width, $height, $pixel, 'png'); - $imagick->setType(Imagick::IMGTYPE_UNDEFINED); - $imagick->setImageType(Imagick::IMGTYPE_UNDEFINED); - $imagick->setColorspace(Imagick::COLORSPACE_SRGB); - $imagick->setImageResolution(96, 96); - - return $imagick; - } -} diff --git a/src/Drivers/Imagick/Image.php b/src/Drivers/Imagick/Image.php deleted file mode 100644 index 7a91161a..00000000 --- a/src/Drivers/Imagick/Image.php +++ /dev/null @@ -1,224 +0,0 @@ -imagick; - } - - public function setImagick(Imagick $imagick): ImageInterface - { - $this->imagick = $imagick; - - return $this; - } - - public function frame(int $position = 0): 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 addFrame(FrameInterface $frame): ImageInterface - { - $imagick = $frame->core(); - - $imagick->setImageDelay($frame->delay()); - $imagick->setImageDispose($frame->dispose()); - - $size = $frame->size(); - $imagick->setImagePage( - $size->width(), - $size->height(), - $frame->offsetLeft(), - $frame->offsetTop() - ); - - $this->imagick->addImage($imagick); - - return $this; - } - - public function setLoops(int $count): ImageInterface - { - $this->imagick = $this->imagick->coalesceImages(); - $this->imagick->setImageIterations($count); - - return $this; - } - - public function loops(): int - { - return $this->imagick->getImageIterations(); - } - - public function isAnimated(): bool - { - return $this->count() > 1; - } - - public function count(): int - { - return $this->imagick->getNumberImages(); - } - - public function current(): mixed - { - $this->imagick->setIteratorIndex($this->iteratorIndex); - - return new Frame($this->imagick->current()); - } - - public function key(): mixed - { - return $this->iteratorIndex; - } - - public function next(): void - { - $this->iteratorIndex = $this->iteratorIndex + 1; - } - - public function rewind(): void - { - $this->iteratorIndex = 0; - } - - public function valid(): bool - { - try { - $result = $this->imagick->setIteratorIndex($this->iteratorIndex); - } catch (ImagickException $e) { - return false; - } - - return $result; - } - - public function width(): int - { - return $this->frame()->core()->getImageWidth(); - } - - public function height(): int - { - return $this->frame()->core()->getImageHeight(); - } - - /** - * {@inheritdoc} - * - * @see ImageInterface::resolution() - */ - public function resolution(): ResolutionInterface - { - return new Resolution(...$this->frame()->core()->getImageResolution()); - } - - /** - * {@inheritdoc} - * - * @see ImageInterface::pickColor() - */ - public function pickColor(int $x, int $y, int $frame_key = 0): ColorInterface - { - return $this->pixelToColor( - $this->frame($frame_key)->core()->getImagePixelColor($x, $y), - $this->colorspace() - ); - } - - public function colorspace(): ColorspaceInterface - { - return match ($this->imagick->getImageColorspace()) { - Imagick::COLORSPACE_CMYK => new CmykColorspace(), - default => new RgbColorspace(), - }; - } - - /** - * {@inheritdoc} - * - * @see ImageInterface::setColorspace() - */ - public function setColorspace(string|ColorspaceInterface $colorspace): ImageInterface - { - return $this->modify(new ColorspaceModifier($colorspace)); - } - - /** - * {@inheritdoc} - * - * @see ImageInterface::setProfile() - */ - public function setProfile(string|ProfileInterface $input): ImageInterface - { - $profile = is_object($input) ? $input : new Profile(file_get_contents($input)); - - return $this->modify(new ProfileModifier($profile)); - } - - /** - * {@inheritdoc} - * - * @see ImageInterface::profile() - */ - public function profile(): ProfileInterface - { - $profiles = $this->imagick->getImageProfiles('icc'); - - if (!array_key_exists('icc', $profiles)) { - throw new ColorException('No ICC profile found.'); - } - - return new Profile($profiles['icc']); - } - - /** - * {@inheritdoc} - * - * @see ImageInterface::removeProfile() - */ - public function removeProfile(): ImageInterface - { - return $this->modify(new ProfileRemovalModifier()); - } -}