mirror of
https://github.com/Intervention/image.git
synced 2025-08-12 17:03:59 +02:00
Remove unused code
This commit is contained in:
@@ -1,406 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Intervention\Image\Drivers\Abstract;
|
||||
|
||||
use Intervention\Image\Collection;
|
||||
use Intervention\Image\EncodedImage;
|
||||
use Intervention\Image\Geometry\Circle;
|
||||
use Intervention\Image\Geometry\Ellipse;
|
||||
use Intervention\Image\Geometry\Line;
|
||||
use Intervention\Image\Geometry\Point;
|
||||
use Intervention\Image\Geometry\Polygon;
|
||||
use Intervention\Image\Geometry\Rectangle;
|
||||
use Intervention\Image\Interfaces\CollectionInterface;
|
||||
use Intervention\Image\Interfaces\EncoderInterface;
|
||||
use Intervention\Image\Interfaces\ImageInterface;
|
||||
use Intervention\Image\Interfaces\ModifierInterface;
|
||||
use Intervention\Image\Interfaces\SizeInterface;
|
||||
use Intervention\Image\Traits\CanHandleInput;
|
||||
use Intervention\Image\Traits\CanResolveDriverClass;
|
||||
use Intervention\Image\Traits\CanRunCallback;
|
||||
|
||||
abstract class DELETE___AbstractImage implements ImageInterface
|
||||
{
|
||||
use CanResolveDriverClass;
|
||||
use CanHandleInput;
|
||||
use CanRunCallback;
|
||||
|
||||
protected Collection $exif;
|
||||
|
||||
public function mapFrames(callable $callback): ImageInterface
|
||||
{
|
||||
foreach ($this as $frame) {
|
||||
$callback($frame);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function size(): SizeInterface
|
||||
{
|
||||
return new Rectangle($this->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')
|
||||
);
|
||||
}
|
||||
}
|
@@ -1,60 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Intervention\Image\Drivers\Abstract;
|
||||
|
||||
use Intervention\Image\Drivers\Abstract\Decoders\AbstractDecoder;
|
||||
use Intervention\Image\Exceptions\DecoderException;
|
||||
use Intervention\Image\Interfaces\ColorInterface;
|
||||
use Intervention\Image\Interfaces\ImageInterface;
|
||||
use Intervention\Image\Interfaces\InputHandlerInterface;
|
||||
|
||||
abstract class DELETE____AbstractInputHandler implements InputHandlerInterface
|
||||
{
|
||||
/**
|
||||
* Array of decoders which will be stacked into to the input handler chain
|
||||
*/
|
||||
protected array $decoders = [];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see InputHandlerInterface::__construct()
|
||||
*/
|
||||
public function __construct(array $decoders = [])
|
||||
{
|
||||
$this->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;
|
||||
}
|
||||
}
|
@@ -1,153 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Intervention\Image\Drivers\Abstract\Decoders;
|
||||
|
||||
use Exception;
|
||||
use Intervention\Image\Exceptions\DecoderException;
|
||||
use Intervention\Image\Interfaces\ColorInterface;
|
||||
use Intervention\Image\Interfaces\DecoderInterface;
|
||||
use Intervention\Image\Interfaces\ImageInterface;
|
||||
use Intervention\Image\Traits\CanBuildFilePointer;
|
||||
|
||||
abstract class DELETE___AbstractDecoder implements DecoderInterface
|
||||
{
|
||||
use CanBuildFilePointer;
|
||||
|
||||
public function __construct(protected ?AbstractDecoder $successor = null)
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
final public function handle($input): ImageInterface|ColorInterface
|
||||
{
|
||||
try {
|
||||
$decoded = $this->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<mediatype>\w+\/[-+.\w]+)?" .
|
||||
"(?P<parameters>(;[-\w]+=[-\w]+)*)(?P<base64>;base64)?,(?P<data>.*)/";
|
||||
|
||||
$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;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
@@ -1,92 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Intervention\Image\Drivers\Abstract\Modifiers;
|
||||
|
||||
use Intervention\Image\Exceptions\DecoderException;
|
||||
use Intervention\Image\Exceptions\GeometryException;
|
||||
use Intervention\Image\Geometry\Ellipse;
|
||||
use Intervention\Image\Geometry\Line;
|
||||
use Intervention\Image\Geometry\Polygon;
|
||||
use Intervention\Image\Geometry\Rectangle;
|
||||
use Intervention\Image\Interfaces\ColorInterface;
|
||||
use Intervention\Image\Interfaces\DrawableInterface;
|
||||
use Intervention\Image\Interfaces\PointInterface;
|
||||
use Intervention\Image\Traits\CanCheckType;
|
||||
use Intervention\Image\Traits\CanHandleInput;
|
||||
|
||||
class DELETE__AbstractDrawModifier
|
||||
{
|
||||
use CanHandleInput;
|
||||
use CanCheckType;
|
||||
|
||||
public function drawable(): DrawableInterface
|
||||
{
|
||||
return $this->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();
|
||||
}
|
||||
}
|
@@ -1,35 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Intervention\Image\Drivers\Abstract\Modifiers;
|
||||
|
||||
use Intervention\Image\Geometry\Rectangle;
|
||||
use Intervention\Image\Interfaces\ImageInterface;
|
||||
use Intervention\Image\Interfaces\SizeInterface;
|
||||
|
||||
abstract class DELETE___AbstractFitModifier
|
||||
{
|
||||
public function __construct(
|
||||
protected int $width,
|
||||
protected int $height,
|
||||
protected string $position = 'center'
|
||||
) {
|
||||
}
|
||||
|
||||
protected function getCropSize(ImageInterface $image): SizeInterface
|
||||
{
|
||||
$imagesize = $image->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);
|
||||
}
|
||||
}
|
@@ -1,34 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Intervention\Image\Drivers\Abstract\Modifiers;
|
||||
|
||||
use Intervention\Image\Geometry\Rectangle;
|
||||
use Intervention\Image\Interfaces\ImageInterface;
|
||||
use Intervention\Image\Interfaces\SizeInterface;
|
||||
use Intervention\Image\Traits\CanCheckType;
|
||||
|
||||
abstract class DELETE___AbstractPadModifier
|
||||
{
|
||||
use CanCheckType;
|
||||
|
||||
public function __construct(
|
||||
protected int $width,
|
||||
protected int $height,
|
||||
protected $background = 'ffffff',
|
||||
protected string $position = 'center'
|
||||
) {
|
||||
//
|
||||
}
|
||||
|
||||
public function getCropSize(ImageInterface $image): SizeInterface
|
||||
{
|
||||
return $image->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);
|
||||
}
|
||||
}
|
@@ -1,29 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Intervention\Image\Drivers\Abstract\Modifiers;
|
||||
|
||||
use Intervention\Image\Exceptions\InputException;
|
||||
use Intervention\Image\Interfaces\FrameInterface;
|
||||
use Intervention\Image\Interfaces\ModifierInterface;
|
||||
|
||||
abstract class DELETE___AbstractRemoveAnimationModifier implements ModifierInterface
|
||||
{
|
||||
protected function chosenFrame($image, int|string $position): FrameInterface
|
||||
{
|
||||
if (is_int($position)) {
|
||||
return $image->frame($position);
|
||||
}
|
||||
|
||||
if (preg_match("/^(?P<percent>[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);
|
||||
}
|
||||
}
|
@@ -1,40 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Intervention\Image\Drivers\Abstract\Modifiers;
|
||||
|
||||
use Intervention\Image\Exceptions\DecoderException;
|
||||
use Intervention\Image\Exceptions\TypeException;
|
||||
use Intervention\Image\Interfaces\ColorInterface;
|
||||
use Intervention\Image\Traits\CanCheckType;
|
||||
use Intervention\Image\Traits\CanHandleInput;
|
||||
|
||||
abstract class DELETE____AbstractRotateModifier
|
||||
{
|
||||
use CanHandleInput;
|
||||
use CanCheckType;
|
||||
|
||||
public function __construct(protected float $angle, protected $background)
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Restrict rotations beyond 360 degrees
|
||||
* because the end result is the same
|
||||
*
|
||||
* @return float
|
||||
*/
|
||||
protected function rotationAngle(): float
|
||||
{
|
||||
return fmod($this->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.");
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,91 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Intervention\Image\Drivers\Gd;
|
||||
|
||||
use Intervention\Image\Collection;
|
||||
use Intervention\Image\Colors\Rgb\Channels\Alpha;
|
||||
use Intervention\Image\Drivers\Gd\Frame;
|
||||
use Intervention\Image\Drivers\Gd\Image;
|
||||
use Intervention\Image\Drivers\Gd\Traits\CanHandleColors;
|
||||
use Intervention\Image\Interfaces\ColorInterface;
|
||||
use Intervention\Image\Interfaces\FactoryInterface;
|
||||
use Intervention\Image\Interfaces\ImageInterface;
|
||||
use Intervention\Image\Traits\CanHandleInput;
|
||||
|
||||
class DELETE___Factory implements FactoryInterface
|
||||
{
|
||||
use CanHandleInput;
|
||||
use CanHandleColors;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see FactoryInterface::newImage()
|
||||
*/
|
||||
public function newImage(int $width, int $height): ImageInterface
|
||||
{
|
||||
return new Image(
|
||||
new Collection([
|
||||
new Frame($this->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;
|
||||
}
|
||||
}
|
@@ -1,177 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Intervention\Image\Drivers\Gd;
|
||||
|
||||
use Intervention\Image\Collection;
|
||||
use Intervention\Image\Colors\Rgb\Colorspace as RgbColorspace;
|
||||
use Intervention\Image\Drivers\Abstract\AbstractImage;
|
||||
use Intervention\Image\Drivers\Gd\Traits\CanHandleColors;
|
||||
use Intervention\Image\Exceptions\AnimationException;
|
||||
use Intervention\Image\Exceptions\GeometryException;
|
||||
use Intervention\Image\Exceptions\NotSupportedException;
|
||||
use Intervention\Image\Interfaces\ColorInterface;
|
||||
use Intervention\Image\Interfaces\ColorspaceInterface;
|
||||
use Intervention\Image\Interfaces\FrameInterface;
|
||||
use Intervention\Image\Interfaces\ImageInterface;
|
||||
use Intervention\Image\Interfaces\ProfileInterface;
|
||||
use Intervention\Image\Interfaces\ResolutionInterface;
|
||||
use Intervention\Image\Resolution;
|
||||
use IteratorAggregate;
|
||||
use Traversable;
|
||||
|
||||
class DELETE__Image extends AbstractImage implements ImageInterface, IteratorAggregate
|
||||
{
|
||||
use CanHandleColors;
|
||||
|
||||
public function __construct(protected Collection $frames, protected int $loops = 0)
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
public function frames(): Collection
|
||||
{
|
||||
return $this->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.');
|
||||
}
|
||||
}
|
@@ -1,110 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Intervention\Image\Drivers\Gd\Traits;
|
||||
|
||||
use GdImage;
|
||||
use Intervention\Image\Colors\Rgb\Color;
|
||||
use Intervention\Image\Interfaces\ColorInterface;
|
||||
use Intervention\Image\Colors\Rgb\Channels\Alpha;
|
||||
use Intervention\Image\Colors\Rgb\Channels\Blue;
|
||||
use Intervention\Image\Colors\Rgb\Channels\Green;
|
||||
use Intervention\Image\Colors\Rgb\Channels\Red;
|
||||
|
||||
trait DELETE___CanHandleColors
|
||||
{
|
||||
/**
|
||||
* Allocate given color in given gd image and return color value/index
|
||||
*
|
||||
* @param GdImage $gd
|
||||
* @param ColorInterface $color
|
||||
* @return int
|
||||
*/
|
||||
protected function allocateColor(GdImage $gd, ColorInterface $color): int
|
||||
{
|
||||
return imagecolorallocatealpha(
|
||||
$gd,
|
||||
$color->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);
|
||||
}
|
||||
}
|
@@ -1,89 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Intervention\Image\Drivers\Imagick;
|
||||
|
||||
use Imagick;
|
||||
use ImagickPixel;
|
||||
use Intervention\Image\Colors\Rgb\Colorspace;
|
||||
use Intervention\Image\Drivers\Imagick\Image;
|
||||
use Intervention\Image\Drivers\Imagick\Traits\CanHandleColors;
|
||||
use Intervention\Image\Interfaces\ColorInterface;
|
||||
use Intervention\Image\Interfaces\FactoryInterface;
|
||||
use Intervention\Image\Interfaces\ImageInterface;
|
||||
use Intervention\Image\Traits\CanCheckType;
|
||||
use Intervention\Image\Traits\CanHandleInput;
|
||||
|
||||
class DELETE___FactoryFactory implements FactoryInterface
|
||||
{
|
||||
use CanHandleInput;
|
||||
use CanCheckType;
|
||||
use CanHandleColors;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see FactoryInterface::newImage()
|
||||
*/
|
||||
public function newImage(int $width, int $height): ImageInterface
|
||||
{
|
||||
return new Image($this->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;
|
||||
}
|
||||
}
|
@@ -1,224 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Intervention\Image\Drivers\Imagick;
|
||||
|
||||
use Imagick;
|
||||
use ImagickException;
|
||||
use Intervention\Image\Colors\Cmyk\Colorspace as CmykColorspace;
|
||||
use Intervention\Image\Colors\Profile;
|
||||
use Intervention\Image\Colors\Rgb\Colorspace as RgbColorspace;
|
||||
use Intervention\Image\Drivers\Abstract\AbstractImage;
|
||||
use Intervention\Image\Drivers\Imagick\Modifiers\ColorspaceModifier;
|
||||
use Intervention\Image\Drivers\Imagick\Modifiers\ProfileModifier;
|
||||
use Intervention\Image\Drivers\Imagick\Modifiers\ProfileRemovalModifier;
|
||||
use Intervention\Image\Drivers\Imagick\Traits\CanHandleColors;
|
||||
use Intervention\Image\Exceptions\AnimationException;
|
||||
use Intervention\Image\Exceptions\ColorException;
|
||||
use Intervention\Image\Interfaces\ColorInterface;
|
||||
use Intervention\Image\Interfaces\ColorspaceInterface;
|
||||
use Intervention\Image\Interfaces\FrameInterface;
|
||||
use Intervention\Image\Interfaces\ImageInterface;
|
||||
use Intervention\Image\Interfaces\ProfileInterface;
|
||||
use Intervention\Image\Interfaces\ResolutionInterface;
|
||||
use Intervention\Image\Resolution;
|
||||
use Iterator;
|
||||
|
||||
class DELETE__Image extends AbstractImage implements ImageInterface, Iterator
|
||||
{
|
||||
use CanHandleColors;
|
||||
|
||||
protected $iteratorIndex = 0;
|
||||
|
||||
public function __construct(protected Imagick $imagick)
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
public function getImagick(): Imagick
|
||||
{
|
||||
return $this->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());
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user