1083 lines
26 KiB
PHP
Executable File
1083 lines
26 KiB
PHP
Executable File
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace Intervention\Image;
|
|
|
|
use Closure;
|
|
use Intervention\Image\Exceptions\RuntimeException;
|
|
use Traversable;
|
|
use Intervention\Image\Analyzers\ColorspaceAnalyzer;
|
|
use Intervention\Image\Analyzers\HeightAnalyzer;
|
|
use Intervention\Image\Analyzers\PixelColorAnalyzer;
|
|
use Intervention\Image\Analyzers\PixelColorsAnalyzer;
|
|
use Intervention\Image\Analyzers\ProfileAnalyzer;
|
|
use Intervention\Image\Analyzers\ResolutionAnalyzer;
|
|
use Intervention\Image\Analyzers\WidthAnalyzer;
|
|
use Intervention\Image\Encoders\AutoEncoder;
|
|
use Intervention\Image\Encoders\AvifEncoder;
|
|
use Intervention\Image\Encoders\BmpEncoder;
|
|
use Intervention\Image\Encoders\FileExtensionEncoder;
|
|
use Intervention\Image\Encoders\FilePathEncoder;
|
|
use Intervention\Image\Encoders\GifEncoder;
|
|
use Intervention\Image\Encoders\HeicEncoder;
|
|
use Intervention\Image\Encoders\Jpeg2000Encoder;
|
|
use Intervention\Image\Encoders\JpegEncoder;
|
|
use Intervention\Image\Encoders\MediaTypeEncoder;
|
|
use Intervention\Image\Encoders\PngEncoder;
|
|
use Intervention\Image\Encoders\TiffEncoder;
|
|
use Intervention\Image\Encoders\WebpEncoder;
|
|
use Intervention\Image\Exceptions\EncoderException;
|
|
use Intervention\Image\Geometry\Bezier;
|
|
use Intervention\Image\Geometry\Circle;
|
|
use Intervention\Image\Geometry\Ellipse;
|
|
use Intervention\Image\Geometry\Factories\BezierFactory;
|
|
use Intervention\Image\Geometry\Factories\CircleFactory;
|
|
use Intervention\Image\Geometry\Factories\EllipseFactory;
|
|
use Intervention\Image\Geometry\Factories\LineFactory;
|
|
use Intervention\Image\Geometry\Factories\PolygonFactory;
|
|
use Intervention\Image\Geometry\Factories\RectangleFactory;
|
|
use Intervention\Image\Geometry\Line;
|
|
use Intervention\Image\Geometry\Point;
|
|
use Intervention\Image\Geometry\Polygon;
|
|
use Intervention\Image\Geometry\Rectangle;
|
|
use Intervention\Image\Interfaces\AnalyzerInterface;
|
|
use Intervention\Image\Interfaces\CollectionInterface;
|
|
use Intervention\Image\Interfaces\ColorInterface;
|
|
use Intervention\Image\Interfaces\ColorspaceInterface;
|
|
use Intervention\Image\Interfaces\CoreInterface;
|
|
use Intervention\Image\Interfaces\DriverInterface;
|
|
use Intervention\Image\Interfaces\EncodedImageInterface;
|
|
use Intervention\Image\Interfaces\EncoderInterface;
|
|
use Intervention\Image\Interfaces\FontInterface;
|
|
use Intervention\Image\Interfaces\FrameInterface;
|
|
use Intervention\Image\Interfaces\ImageInterface;
|
|
use Intervention\Image\Interfaces\ModifierInterface;
|
|
use Intervention\Image\Interfaces\ProfileInterface;
|
|
use Intervention\Image\Interfaces\ResolutionInterface;
|
|
use Intervention\Image\Interfaces\SizeInterface;
|
|
use Intervention\Image\Modifiers\AlignRotationModifier;
|
|
use Intervention\Image\Modifiers\BlendTransparencyModifier;
|
|
use Intervention\Image\Modifiers\BlurModifier;
|
|
use Intervention\Image\Modifiers\BrightnessModifier;
|
|
use Intervention\Image\Modifiers\ColorizeModifier;
|
|
use Intervention\Image\Modifiers\ColorspaceModifier;
|
|
use Intervention\Image\Modifiers\ContainModifier;
|
|
use Intervention\Image\Modifiers\ContrastModifier;
|
|
use Intervention\Image\Modifiers\CropModifier;
|
|
use Intervention\Image\Modifiers\DrawBezierModifier;
|
|
use Intervention\Image\Modifiers\DrawEllipseModifier;
|
|
use Intervention\Image\Modifiers\DrawLineModifier;
|
|
use Intervention\Image\Modifiers\DrawPixelModifier;
|
|
use Intervention\Image\Modifiers\DrawPolygonModifier;
|
|
use Intervention\Image\Modifiers\DrawRectangleModifier;
|
|
use Intervention\Image\Modifiers\FillModifier;
|
|
use Intervention\Image\Modifiers\CoverDownModifier;
|
|
use Intervention\Image\Modifiers\CoverModifier;
|
|
use Intervention\Image\Modifiers\FlipModifier;
|
|
use Intervention\Image\Modifiers\FlopModifier;
|
|
use Intervention\Image\Modifiers\GammaModifier;
|
|
use Intervention\Image\Modifiers\GreyscaleModifier;
|
|
use Intervention\Image\Modifiers\InvertModifier;
|
|
use Intervention\Image\Modifiers\PadModifier;
|
|
use Intervention\Image\Modifiers\PixelateModifier;
|
|
use Intervention\Image\Modifiers\PlaceModifier;
|
|
use Intervention\Image\Modifiers\ProfileModifier;
|
|
use Intervention\Image\Modifiers\ProfileRemovalModifier;
|
|
use Intervention\Image\Modifiers\QuantizeColorsModifier;
|
|
use Intervention\Image\Modifiers\RemoveAnimationModifier;
|
|
use Intervention\Image\Modifiers\ResizeCanvasModifier;
|
|
use Intervention\Image\Modifiers\ResizeCanvasRelativeModifier;
|
|
use Intervention\Image\Modifiers\ResizeDownModifier;
|
|
use Intervention\Image\Modifiers\ResizeModifier;
|
|
use Intervention\Image\Modifiers\ResolutionModifier;
|
|
use Intervention\Image\Modifiers\RotateModifier;
|
|
use Intervention\Image\Modifiers\ScaleDownModifier;
|
|
use Intervention\Image\Modifiers\ScaleModifier;
|
|
use Intervention\Image\Modifiers\SharpenModifier;
|
|
use Intervention\Image\Modifiers\SliceAnimationModifier;
|
|
use Intervention\Image\Modifiers\TextModifier;
|
|
use Intervention\Image\Modifiers\TrimModifier;
|
|
use Intervention\Image\Typography\FontFactory;
|
|
|
|
final class Image implements ImageInterface
|
|
{
|
|
/**
|
|
* The origin from which the image was created
|
|
*/
|
|
private Origin $origin;
|
|
|
|
/**
|
|
* Create new instance
|
|
*
|
|
* @throws RuntimeException
|
|
* @return void
|
|
*/
|
|
public function __construct(
|
|
private DriverInterface $driver,
|
|
private CoreInterface $core,
|
|
private CollectionInterface $exif = new Collection()
|
|
) {
|
|
$this->origin = new Origin();
|
|
}
|
|
|
|
/**
|
|
* {@inheritdoc}
|
|
*
|
|
* @see ImageInterface::driver()
|
|
*/
|
|
public function driver(): DriverInterface
|
|
{
|
|
return $this->driver;
|
|
}
|
|
|
|
/**
|
|
* {@inheritdoc}
|
|
*
|
|
* @see ImageInterface::core()
|
|
*/
|
|
public function core(): CoreInterface
|
|
{
|
|
return $this->core;
|
|
}
|
|
|
|
/**
|
|
* {@inheritdoc}
|
|
*
|
|
* @see ImageInterface::origin()
|
|
*/
|
|
public function origin(): Origin
|
|
{
|
|
return $this->origin;
|
|
}
|
|
|
|
/**
|
|
* {@inheritdoc}
|
|
*
|
|
* @see ImageInterface::setOrigin()
|
|
*/
|
|
public function setOrigin(Origin $origin): ImageInterface
|
|
{
|
|
$this->origin = $origin;
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* {@inheritdoc}
|
|
*
|
|
* @see ImageInterface::count()
|
|
*/
|
|
public function count(): int
|
|
{
|
|
return $this->core->count();
|
|
}
|
|
|
|
/**
|
|
* Implementation of IteratorAggregate
|
|
*
|
|
* @return Traversable<FrameInterface>
|
|
*/
|
|
public function getIterator(): Traversable
|
|
{
|
|
return $this->core;
|
|
}
|
|
|
|
/**
|
|
* {@inheritdoc}
|
|
*
|
|
* @see ImageInterface::isAnimated()
|
|
*/
|
|
public function isAnimated(): bool
|
|
{
|
|
return $this->count() > 1;
|
|
}
|
|
|
|
/**
|
|
* {@inheritdoc}
|
|
*
|
|
* @see ImageInterface::removeAnimation(
|
|
*/
|
|
public function removeAnimation(int|string $position = 0): ImageInterface
|
|
{
|
|
return $this->modify(new RemoveAnimationModifier($position));
|
|
}
|
|
|
|
/**
|
|
* {@inheritdoc}
|
|
*
|
|
* @see ImageInterface::sliceAnimation()
|
|
*/
|
|
public function sliceAnimation(int $offset = 0, ?int $length = null): ImageInterface
|
|
{
|
|
return $this->modify(new SliceAnimationModifier($offset, $length));
|
|
}
|
|
|
|
/**
|
|
* {@inheritdoc}
|
|
*
|
|
* @see ImageInterface::loops()
|
|
*/
|
|
public function loops(): int
|
|
{
|
|
return $this->core->loops();
|
|
}
|
|
|
|
/**
|
|
* {@inheritdoc}
|
|
*
|
|
* @see ImageInterface::setLoops()
|
|
*/
|
|
public function setLoops(int $loops): ImageInterface
|
|
{
|
|
$this->core->setLoops($loops);
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* {@inheritdoc}
|
|
*
|
|
* @see ImageInterface::exif()
|
|
*/
|
|
public function exif(?string $query = null): mixed
|
|
{
|
|
return is_null($query) ? $this->exif : $this->exif->get($query);
|
|
}
|
|
|
|
/**
|
|
* {@inheritdoc}
|
|
*
|
|
* @see ImageInterface::setExif()
|
|
*/
|
|
public function setExif(CollectionInterface $exif): ImageInterface
|
|
{
|
|
$this->exif = $exif;
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* {@inheritdoc}
|
|
*
|
|
* @see ImageInterface::modify()
|
|
*/
|
|
public function modify(ModifierInterface $modifier): ImageInterface
|
|
{
|
|
return $this->driver->specialize($modifier)->apply($this);
|
|
}
|
|
|
|
/**
|
|
* {@inheritdoc}
|
|
*
|
|
* @see ImageInterface::analyze()
|
|
*/
|
|
public function analyze(AnalyzerInterface $analyzer): mixed
|
|
{
|
|
return $this->driver->specialize($analyzer)->analyze($this);
|
|
}
|
|
|
|
/**
|
|
* {@inheritdoc}
|
|
*
|
|
* @see ImageInterface::encode()
|
|
*/
|
|
public function encode(EncoderInterface $encoder = new AutoEncoder()): EncodedImageInterface
|
|
{
|
|
return $this->driver->specialize($encoder)->encode($this);
|
|
}
|
|
|
|
/**
|
|
* {@inheritdoc}
|
|
*
|
|
* @see ImageInterface::save()
|
|
*/
|
|
public function save(?string $path = null, mixed ...$options): ImageInterface
|
|
{
|
|
$path = is_null($path) ? $this->origin()->filePath() : $path;
|
|
|
|
if (is_null($path)) {
|
|
throw new EncoderException('Could not determine file path to save.');
|
|
}
|
|
|
|
try {
|
|
// try to determine encoding format by file extension of the path
|
|
$encoded = $this->encodeByPath($path, ...$options);
|
|
} catch (EncoderException) {
|
|
// fallback to encoding format by media type
|
|
$encoded = $this->encodeByMediaType(null, ...$options);
|
|
}
|
|
|
|
$encoded->save($path);
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* {@inheritdoc}
|
|
*
|
|
* @see ImageInterface::width()
|
|
*/
|
|
public function width(): int
|
|
{
|
|
return $this->analyze(new WidthAnalyzer());
|
|
}
|
|
|
|
/**
|
|
* {@inheritdoc}
|
|
*
|
|
* @see ImageInterface::height()
|
|
*/
|
|
public function height(): int
|
|
{
|
|
return $this->analyze(new HeightAnalyzer());
|
|
}
|
|
|
|
/**
|
|
* {@inheritdoc}
|
|
*
|
|
* @see ImageInterface::size()
|
|
*/
|
|
public function size(): SizeInterface
|
|
{
|
|
return new Rectangle($this->width(), $this->height());
|
|
}
|
|
|
|
/**
|
|
* {@inheritdoc}
|
|
*
|
|
* @see ImageInterface::colorspace()
|
|
*/
|
|
public function colorspace(): ColorspaceInterface
|
|
{
|
|
return $this->analyze(new ColorspaceAnalyzer());
|
|
}
|
|
|
|
/**
|
|
* {@inheritdoc}
|
|
*
|
|
* @see ImageInterface::setColorspace()
|
|
*/
|
|
public function setColorspace(string|ColorspaceInterface $colorspace): ImageInterface
|
|
{
|
|
return $this->modify(new ColorspaceModifier($colorspace));
|
|
}
|
|
|
|
/**
|
|
* {@inheritdoc}
|
|
*
|
|
* @see ImageInterface::resolution()
|
|
*/
|
|
public function resolution(): ResolutionInterface
|
|
{
|
|
return $this->analyze(new ResolutionAnalyzer());
|
|
}
|
|
|
|
/**
|
|
* {@inheritdoc}
|
|
*
|
|
* @see ImageInterface::setResolution()
|
|
*/
|
|
public function setResolution(float $x, float $y): ImageInterface
|
|
{
|
|
return $this->modify(new ResolutionModifier($x, $y));
|
|
}
|
|
|
|
/**
|
|
* {@inheritdoc}
|
|
*
|
|
* @see ImageInterface::pickColor()
|
|
*/
|
|
public function pickColor(int $x, int $y, int $frame_key = 0): ColorInterface
|
|
{
|
|
return $this->analyze(new PixelColorAnalyzer($x, $y, $frame_key));
|
|
}
|
|
|
|
/**
|
|
* {@inheritdoc}
|
|
*
|
|
* @see ImageInterface::pickColors()
|
|
*/
|
|
public function pickColors(int $x, int $y): CollectionInterface
|
|
{
|
|
return $this->analyze(new PixelColorsAnalyzer($x, $y));
|
|
}
|
|
|
|
/**
|
|
* {@inheritdoc}
|
|
*
|
|
* @see ImageInterface::blendingColor()
|
|
*/
|
|
public function blendingColor(): ColorInterface
|
|
{
|
|
return $this->driver()->handleInput(
|
|
$this->driver()->config()->blendingColor
|
|
);
|
|
}
|
|
|
|
/**
|
|
* {@inheritdoc}
|
|
*
|
|
* @see ImageInterface::setBlendingColor()
|
|
*/
|
|
public function setBlendingColor(mixed $color): ImageInterface
|
|
{
|
|
$this->driver()->config()->setOptions(
|
|
blendingColor: $this->driver()->handleInput($color)
|
|
);
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* {@inheritdoc}
|
|
*
|
|
* @see ImageInterface::blendTransparency()
|
|
*/
|
|
public function blendTransparency(mixed $color = null): ImageInterface
|
|
{
|
|
return $this->modify(new BlendTransparencyModifier($color));
|
|
}
|
|
|
|
/**
|
|
* {@inheritdoc}
|
|
*
|
|
* @see ImageInterface::profile()
|
|
*/
|
|
public function profile(): ProfileInterface
|
|
{
|
|
return $this->analyze(new ProfileAnalyzer());
|
|
}
|
|
|
|
/**
|
|
* {@inheritdoc}
|
|
*
|
|
* @see ImageInterface::setProfile()
|
|
*/
|
|
public function setProfile(ProfileInterface $profile): ImageInterface
|
|
{
|
|
return $this->modify(new ProfileModifier($profile));
|
|
}
|
|
|
|
/**
|
|
* {@inheritdoc}
|
|
*
|
|
* @see ImageInterface::removeProfile()
|
|
*/
|
|
public function removeProfile(): ImageInterface
|
|
{
|
|
return $this->modify(new ProfileRemovalModifier());
|
|
}
|
|
|
|
/**
|
|
* {@inheritdoc}
|
|
*
|
|
* @see ImageInterface::reduceColors()
|
|
*/
|
|
public function reduceColors(int $limit, mixed $background = 'transparent'): ImageInterface
|
|
{
|
|
return $this->modify(new QuantizeColorsModifier($limit, $background));
|
|
}
|
|
|
|
/**
|
|
* {@inheritdoc}
|
|
*
|
|
* @see ImageInterface::sharpen()
|
|
*/
|
|
public function sharpen(int $amount = 10): ImageInterface
|
|
{
|
|
return $this->modify(new SharpenModifier($amount));
|
|
}
|
|
|
|
/**
|
|
* {@inheritdoc}
|
|
*
|
|
* @see ImageInterface::invert()
|
|
*/
|
|
public function invert(): ImageInterface
|
|
{
|
|
return $this->modify(new InvertModifier());
|
|
}
|
|
|
|
/**
|
|
* {@inheritdoc}
|
|
*
|
|
* @see ImageInterface::pixelate()
|
|
*/
|
|
public function pixelate(int $size): ImageInterface
|
|
{
|
|
return $this->modify(new PixelateModifier($size));
|
|
}
|
|
|
|
/**
|
|
* {@inheritdoc}
|
|
*
|
|
* @see ImageInterface::greyscale()
|
|
*/
|
|
public function greyscale(): ImageInterface
|
|
{
|
|
return $this->modify(new GreyscaleModifier());
|
|
}
|
|
|
|
/**
|
|
* {@inheritdoc}
|
|
*
|
|
* @see ImageInterface::brightness()
|
|
*/
|
|
public function brightness(int $level): ImageInterface
|
|
{
|
|
return $this->modify(new BrightnessModifier($level));
|
|
}
|
|
|
|
/**
|
|
* {@inheritdoc}
|
|
*
|
|
* @see ImageInterface::contrast()
|
|
*/
|
|
public function contrast(int $level): ImageInterface
|
|
{
|
|
return $this->modify(new ContrastModifier($level));
|
|
}
|
|
|
|
/**
|
|
* {@inheritdoc}
|
|
*
|
|
* @see ImageInterface::gamma()
|
|
*/
|
|
public function gamma(float $gamma): ImageInterface
|
|
{
|
|
return $this->modify(new GammaModifier($gamma));
|
|
}
|
|
|
|
/**
|
|
* {@inheritdoc}
|
|
*
|
|
* @see ImageInterface::colorize()
|
|
*/
|
|
public function colorize(int $red = 0, int $green = 0, int $blue = 0): ImageInterface
|
|
{
|
|
return $this->modify(new ColorizeModifier($red, $green, $blue));
|
|
}
|
|
|
|
/**
|
|
* {@inheritdoc}
|
|
*
|
|
* @see ImageInterface::flip()
|
|
*/
|
|
public function flip(): ImageInterface
|
|
{
|
|
return $this->modify(new FlipModifier());
|
|
}
|
|
|
|
/**
|
|
* {@inheritdoc}
|
|
*
|
|
* @see ImageInterface::flop()
|
|
*/
|
|
public function flop(): ImageInterface
|
|
{
|
|
return $this->modify(new FlopModifier());
|
|
}
|
|
|
|
/**
|
|
* {@inheritdoc}
|
|
*
|
|
* @see ImageInterface::blur()
|
|
*/
|
|
public function blur(int $amount = 5): ImageInterface
|
|
{
|
|
return $this->modify(new BlurModifier($amount));
|
|
}
|
|
|
|
/**
|
|
* {@inheritdoc}
|
|
*
|
|
* @see ImageInterface::rotate()
|
|
*/
|
|
public function rotate(float $angle, mixed $background = 'ffffff'): ImageInterface
|
|
{
|
|
return $this->modify(new RotateModifier($angle, $background));
|
|
}
|
|
|
|
/**
|
|
* {@inheritdoc}
|
|
*
|
|
* @see ImageInterface::orient()
|
|
*/
|
|
public function orient(): ImageInterface
|
|
{
|
|
return $this->modify(new AlignRotationModifier());
|
|
}
|
|
|
|
/**
|
|
* {@inheritdoc}
|
|
*
|
|
* @see ImageInterface::text()
|
|
*/
|
|
public function text(string $text, int $x, int $y, callable|Closure|FontInterface $font): ImageInterface
|
|
{
|
|
return $this->modify(
|
|
new TextModifier(
|
|
$text,
|
|
new Point($x, $y),
|
|
call_user_func(new FontFactory($font)),
|
|
),
|
|
);
|
|
}
|
|
|
|
/**
|
|
* {@inheritdoc}
|
|
*
|
|
* @see ImageInterface::resize()
|
|
*/
|
|
public function resize(?int $width = null, ?int $height = null): ImageInterface
|
|
{
|
|
return $this->modify(new ResizeModifier($width, $height));
|
|
}
|
|
|
|
/**
|
|
* {@inheritdoc}
|
|
*
|
|
* @see ImageInterface::resizeDown()
|
|
*/
|
|
public function resizeDown(?int $width = null, ?int $height = null): ImageInterface
|
|
{
|
|
return $this->modify(new ResizeDownModifier($width, $height));
|
|
}
|
|
|
|
/**
|
|
* {@inheritdoc}
|
|
*
|
|
* @see ImageInterface::scale()
|
|
*/
|
|
public function scale(?int $width = null, ?int $height = null): ImageInterface
|
|
{
|
|
return $this->modify(new ScaleModifier($width, $height));
|
|
}
|
|
|
|
/**
|
|
* {@inheritdoc}
|
|
*
|
|
* @see ImageInterface::scaleDown()
|
|
*/
|
|
public function scaleDown(?int $width = null, ?int $height = null): ImageInterface
|
|
{
|
|
return $this->modify(new ScaleDownModifier($width, $height));
|
|
}
|
|
|
|
/**
|
|
* {@inheritdoc}
|
|
*
|
|
* @see ImageInterface::cover()
|
|
*/
|
|
public function cover(int $width, int $height, string $position = 'center'): ImageInterface
|
|
{
|
|
return $this->modify(new CoverModifier($width, $height, $position));
|
|
}
|
|
|
|
/**
|
|
* {@inheritdoc}
|
|
*
|
|
* @see ImageInterface::coverDown()
|
|
*/
|
|
public function coverDown(int $width, int $height, string $position = 'center'): ImageInterface
|
|
{
|
|
return $this->modify(new CoverDownModifier($width, $height, $position));
|
|
}
|
|
|
|
/**
|
|
* {@inheritdoc}
|
|
*
|
|
* @see ImageInterface::resizeCanvas()
|
|
*/
|
|
public function resizeCanvas(
|
|
?int $width = null,
|
|
?int $height = null,
|
|
mixed $background = 'ffffff',
|
|
string $position = 'center'
|
|
): ImageInterface {
|
|
return $this->modify(new ResizeCanvasModifier($width, $height, $background, $position));
|
|
}
|
|
|
|
/**
|
|
* {@inheritdoc}
|
|
*
|
|
* @see ImageInterface::resizeCanvasRelative()
|
|
*/
|
|
public function resizeCanvasRelative(
|
|
?int $width = null,
|
|
?int $height = null,
|
|
mixed $background = 'ffffff',
|
|
string $position = 'center'
|
|
): ImageInterface {
|
|
return $this->modify(new ResizeCanvasRelativeModifier($width, $height, $background, $position));
|
|
}
|
|
|
|
/**
|
|
* {@inheritdoc}
|
|
*
|
|
* @see ImageInterface::padDown()
|
|
*/
|
|
public function pad(
|
|
int $width,
|
|
int $height,
|
|
mixed $background = 'ffffff',
|
|
string $position = 'center'
|
|
): ImageInterface {
|
|
return $this->modify(new PadModifier($width, $height, $background, $position));
|
|
}
|
|
|
|
/**
|
|
* {@inheritdoc}
|
|
*
|
|
* @see ImageInterface::pad()
|
|
*/
|
|
public function contain(
|
|
int $width,
|
|
int $height,
|
|
mixed $background = 'ffffff',
|
|
string $position = 'center'
|
|
): ImageInterface {
|
|
return $this->modify(new ContainModifier($width, $height, $background, $position));
|
|
}
|
|
|
|
/**
|
|
* {@inheritdoc}
|
|
*
|
|
* @see ImageInterface::crop()
|
|
*/
|
|
public function crop(
|
|
int $width,
|
|
int $height,
|
|
int $offset_x = 0,
|
|
int $offset_y = 0,
|
|
mixed $background = 'ffffff',
|
|
string $position = 'top-left'
|
|
): ImageInterface {
|
|
return $this->modify(new CropModifier($width, $height, $offset_x, $offset_y, $background, $position));
|
|
}
|
|
|
|
/**
|
|
* {@inheritdoc}
|
|
*
|
|
* @see ImageInterface::trim()
|
|
*/
|
|
public function trim(int $tolerance = 0): ImageInterface
|
|
{
|
|
return $this->modify(new TrimModifier($tolerance));
|
|
}
|
|
|
|
/**
|
|
* {@inheritdoc}
|
|
*
|
|
* @see ImageInterface::place()
|
|
*/
|
|
public function place(
|
|
mixed $element,
|
|
string $position = 'top-left',
|
|
int $offset_x = 0,
|
|
int $offset_y = 0,
|
|
int $opacity = 100
|
|
): ImageInterface {
|
|
return $this->modify(new PlaceModifier($element, $position, $offset_x, $offset_y, $opacity));
|
|
}
|
|
|
|
/**
|
|
* {@inheritdoc}
|
|
*
|
|
* @see ImageInterface::fill()
|
|
*/
|
|
public function fill(mixed $color, ?int $x = null, ?int $y = null): ImageInterface
|
|
{
|
|
return $this->modify(
|
|
new FillModifier(
|
|
$color,
|
|
is_null($x) || is_null($y) ? null : new Point($x, $y),
|
|
),
|
|
);
|
|
}
|
|
|
|
/**
|
|
* {@inheritdoc}
|
|
*
|
|
* @see ImageInterface::drawPixel()
|
|
*/
|
|
public function drawPixel(int $x, int $y, mixed $color): ImageInterface
|
|
{
|
|
return $this->modify(new DrawPixelModifier(new Point($x, $y), $color));
|
|
}
|
|
|
|
/**
|
|
* {@inheritdoc}
|
|
*
|
|
* @see ImageInterface::drawRectangle()
|
|
*/
|
|
public function drawRectangle(int $x, int $y, callable|Closure|Rectangle $init): ImageInterface
|
|
{
|
|
return $this->modify(
|
|
new DrawRectangleModifier(
|
|
call_user_func(new RectangleFactory(new Point($x, $y), $init)),
|
|
),
|
|
);
|
|
}
|
|
|
|
/**
|
|
* {@inheritdoc}
|
|
*
|
|
* @see ImageInterface::drawEllipse()
|
|
*/
|
|
public function drawEllipse(int $x, int $y, callable|Closure|Ellipse $init): ImageInterface
|
|
{
|
|
return $this->modify(
|
|
new DrawEllipseModifier(
|
|
call_user_func(new EllipseFactory(new Point($x, $y), $init)),
|
|
),
|
|
);
|
|
}
|
|
|
|
/**
|
|
* {@inheritdoc}
|
|
*
|
|
* @see ImageInterface::drawCircle()
|
|
*/
|
|
public function drawCircle(int $x, int $y, callable|Closure|Circle $init): ImageInterface
|
|
{
|
|
return $this->modify(
|
|
new DrawEllipseModifier(
|
|
call_user_func(new CircleFactory(new Point($x, $y), $init)),
|
|
),
|
|
);
|
|
}
|
|
|
|
/**
|
|
* {@inheritdoc}
|
|
*
|
|
* @see ImageInterface::drawPolygon()
|
|
*/
|
|
public function drawPolygon(callable|Closure|Polygon $init): ImageInterface
|
|
{
|
|
return $this->modify(
|
|
new DrawPolygonModifier(
|
|
call_user_func(new PolygonFactory($init)),
|
|
),
|
|
);
|
|
}
|
|
|
|
/**
|
|
* {@inheritdoc}
|
|
*
|
|
* @see ImageInterface::drawLine()
|
|
*/
|
|
public function drawLine(callable|Closure|Line $init): ImageInterface
|
|
{
|
|
return $this->modify(
|
|
new DrawLineModifier(
|
|
call_user_func(new LineFactory($init)),
|
|
),
|
|
);
|
|
}
|
|
|
|
/**
|
|
* {@inheritdoc}
|
|
*
|
|
* @see ImageInterface::drawBezier()
|
|
*/
|
|
public function drawBezier(callable|Closure|Bezier $init): ImageInterface
|
|
{
|
|
return $this->modify(
|
|
new DrawBezierModifier(
|
|
call_user_func(new BezierFactory($init)),
|
|
),
|
|
);
|
|
}
|
|
|
|
/**
|
|
* {@inheritdoc}
|
|
*
|
|
* @see ImageInterface::encodeByMediaType()
|
|
*/
|
|
public function encodeByMediaType(null|string|MediaType $type = null, mixed ...$options): EncodedImageInterface
|
|
{
|
|
return $this->encode(new MediaTypeEncoder($type, ...$options));
|
|
}
|
|
|
|
/**
|
|
* {@inheritdoc}
|
|
*
|
|
* @see ImageInterface::encodeByExtension()
|
|
*/
|
|
public function encodeByExtension(
|
|
null|string|FileExtension $extension = null,
|
|
mixed ...$options
|
|
): EncodedImageInterface {
|
|
return $this->encode(new FileExtensionEncoder($extension, ...$options));
|
|
}
|
|
|
|
/**
|
|
* {@inheritdoc}
|
|
*
|
|
* @see ImageInterface::encodeByPath()
|
|
*/
|
|
public function encodeByPath(?string $path = null, mixed ...$options): EncodedImageInterface
|
|
{
|
|
return $this->encode(new FilePathEncoder($path, ...$options));
|
|
}
|
|
|
|
/**
|
|
* {@inheritdoc}
|
|
*
|
|
* @see ImageInterface::toJpeg()
|
|
*/
|
|
public function toJpeg(mixed ...$options): EncodedImageInterface
|
|
{
|
|
return $this->encode(new JpegEncoder(...$options));
|
|
}
|
|
|
|
/**
|
|
* Alias of self::toJpeg()
|
|
*
|
|
* @throws RuntimeException
|
|
*/
|
|
public function toJpg(mixed ...$options): EncodedImageInterface
|
|
{
|
|
return $this->toJpeg(...$options);
|
|
}
|
|
|
|
/**
|
|
* {@inheritdoc}
|
|
*
|
|
* @see ImageInterface::toJpeg()
|
|
*/
|
|
public function toJpeg2000(mixed ...$options): EncodedImageInterface
|
|
{
|
|
return $this->encode(new Jpeg2000Encoder(...$options));
|
|
}
|
|
|
|
/**
|
|
* ALias of self::toJpeg2000()
|
|
*
|
|
* @throws RuntimeException
|
|
*/
|
|
public function toJp2(mixed ...$options): EncodedImageInterface
|
|
{
|
|
return $this->toJpeg2000(...$options);
|
|
}
|
|
|
|
/**
|
|
* {@inheritdoc}
|
|
*
|
|
* @see ImageInterface::toPng()
|
|
*/
|
|
public function toPng(mixed ...$options): EncodedImageInterface
|
|
{
|
|
return $this->encode(new PngEncoder(...$options));
|
|
}
|
|
|
|
/**
|
|
* {@inheritdoc}
|
|
*
|
|
* @see ImageInterface::toGif()
|
|
*/
|
|
public function toGif(mixed ...$options): EncodedImageInterface
|
|
{
|
|
return $this->encode(new GifEncoder(...$options));
|
|
}
|
|
|
|
/**
|
|
* {@inheritdoc}
|
|
*
|
|
* @see ImageInterface::toWebp()
|
|
*/
|
|
public function toWebp(mixed ...$options): EncodedImageInterface
|
|
{
|
|
return $this->encode(new WebpEncoder(...$options));
|
|
}
|
|
|
|
/**
|
|
* {@inheritdoc}
|
|
*
|
|
* @see ImageInterface::toBitmap()
|
|
*/
|
|
public function toBitmap(mixed ...$options): EncodedImageInterface
|
|
{
|
|
return $this->encode(new BmpEncoder(...$options));
|
|
}
|
|
|
|
/**
|
|
* Alias if self::toBitmap()
|
|
*
|
|
* @throws RuntimeException
|
|
*/
|
|
public function toBmp(mixed ...$options): EncodedImageInterface
|
|
{
|
|
return $this->toBitmap(...$options);
|
|
}
|
|
|
|
/**
|
|
* {@inheritdoc}
|
|
*
|
|
* @see ImageInterface::toAvif()
|
|
*/
|
|
public function toAvif(mixed ...$options): EncodedImageInterface
|
|
{
|
|
return $this->encode(new AvifEncoder(...$options));
|
|
}
|
|
|
|
/**
|
|
* {@inheritdoc}
|
|
*
|
|
* @see ImageInterface::toTiff()
|
|
*/
|
|
public function toTiff(mixed ...$options): EncodedImageInterface
|
|
{
|
|
return $this->encode(new TiffEncoder(...$options));
|
|
}
|
|
|
|
/**
|
|
* Alias of self::toTiff()
|
|
*
|
|
* @throws RuntimeException
|
|
*/
|
|
public function toTif(mixed ...$options): EncodedImageInterface
|
|
{
|
|
return $this->toTiff(...$options);
|
|
}
|
|
|
|
/**
|
|
* {@inheritdoc}
|
|
*
|
|
* @see ImageInterface::toHeic()
|
|
*/
|
|
public function toHeic(mixed ...$options): EncodedImageInterface
|
|
{
|
|
return $this->encode(new HeicEncoder(...$options));
|
|
}
|
|
|
|
/**
|
|
* Show debug info for the current image
|
|
*
|
|
* @return array<string, int>
|
|
*/
|
|
public function __debugInfo(): array
|
|
{
|
|
try {
|
|
return [
|
|
'width' => $this->width(),
|
|
'height' => $this->height(),
|
|
];
|
|
} catch (RuntimeException) {
|
|
return [];
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Clone image
|
|
*/
|
|
public function __clone(): void
|
|
{
|
|
$this->driver = clone $this->driver;
|
|
$this->core = clone $this->core;
|
|
$this->exif = clone $this->exif;
|
|
}
|
|
}
|