Вход Регистрация
Файл: vendor/intervention/image/src/Image.php
Строк: 1791
<?php

declare(strict_types=1);

namespace 
InterventionImage;

use 
InterventionImageAnalyzersColorspaceAnalyzer;
use 
InterventionImageAnalyzersHeightAnalyzer;
use 
InterventionImageAnalyzersPixelColorAnalyzer;
use 
InterventionImageAnalyzersPixelColorsAnalyzer;
use 
InterventionImageAnalyzersProfileAnalyzer;
use 
InterventionImageAnalyzersResolutionAnalyzer;
use 
InterventionImageAnalyzersWidthAnalyzer;
use 
InterventionImageEncodersAutoEncoder;
use 
InterventionImageEncodersFileExtensionEncoder;
use 
InterventionImageEncodersFilePathEncoder;
use 
InterventionImageEncodersFormatEncoder;
use 
InterventionImageEncodersMediaTypeEncoder;
use 
InterventionImageExceptionsAnalyzerException;
use 
InterventionImageExceptionsColorDecoderException;
use 
InterventionImageExceptionsDirectoryNotFoundException;
use 
InterventionImageExceptionsEncoderException;
use 
InterventionImageExceptionsFileNotWritableException;
use 
InterventionImageExceptionsInvalidArgumentException;
use 
InterventionImageExceptionsModifierException;
use 
InterventionImageExceptionsNotSupportedException;
use 
InterventionImageExceptionsStateException;
use 
InterventionImageExceptionsStreamException;
use 
InterventionImageGeometryBezier;
use 
InterventionImageGeometryCircle;
use 
InterventionImageGeometryEllipse;
use 
InterventionImageGeometryFactoriesBezierFactory;
use 
InterventionImageGeometryFactoriesCircleFactory;
use 
InterventionImageGeometryFactoriesEllipseFactory;
use 
InterventionImageGeometryFactoriesLineFactory;
use 
InterventionImageGeometryFactoriesPolygonFactory;
use 
InterventionImageGeometryFactoriesRectangleFactory;
use 
InterventionImageGeometryLine;
use 
InterventionImageGeometryPoint;
use 
InterventionImageGeometryPolygon;
use 
InterventionImageGeometryRectangle;
use 
InterventionImageInterfacesAnalyzerInterface;
use 
InterventionImageInterfacesCollectionInterface;
use 
InterventionImageInterfacesColorInterface;
use 
InterventionImageInterfacesColorspaceInterface;
use 
InterventionImageInterfacesCoreInterface;
use 
InterventionImageInterfacesDrawableInterface;
use 
InterventionImageInterfacesDriverInterface;
use 
InterventionImageInterfacesEncodedImageInterface;
use 
InterventionImageInterfacesEncoderInterface;
use 
InterventionImageInterfacesFontInterface;
use 
InterventionImageInterfacesFrameInterface;
use 
InterventionImageInterfacesImageInterface;
use 
InterventionImageInterfacesModifierInterface;
use 
InterventionImageInterfacesOriginInterface;
use 
InterventionImageInterfacesProfileInterface;
use 
InterventionImageInterfacesResolutionInterface;
use 
InterventionImageInterfacesSizeInterface;
use 
InterventionImageModifiersBlurModifier;
use 
InterventionImageModifiersBrightnessModifier;
use 
InterventionImageModifiersColorizeModifier;
use 
InterventionImageModifiersColorspaceModifier;
use 
InterventionImageModifiersContainDownModifier;
use 
InterventionImageModifiersContainModifier;
use 
InterventionImageModifiersContrastModifier;
use 
InterventionImageModifiersCoverDownModifier;
use 
InterventionImageModifiersCoverModifier;
use 
InterventionImageModifiersCropModifier;
use 
InterventionImageModifiersDrawBezierModifier;
use 
InterventionImageModifiersDrawEllipseModifier;
use 
InterventionImageModifiersDrawLineModifier;
use 
InterventionImageModifiersDrawPixelModifier;
use 
InterventionImageModifiersDrawPolygonModifier;
use 
InterventionImageModifiersDrawRectangleModifier;
use 
InterventionImageModifiersFillModifier;
use 
InterventionImageModifiersFillTransparentAreasModifier;
use 
InterventionImageModifiersFlipModifier;
use 
InterventionImageModifiersGammaModifier;
use 
InterventionImageModifiersGrayscaleModifier;
use 
InterventionImageModifiersInsertModifier;
use 
InterventionImageModifiersInvertModifier;
use 
InterventionImageModifiersOrientModifier;
use 
InterventionImageModifiersPixelateModifier;
use 
InterventionImageModifiersProfileModifier;
use 
InterventionImageModifiersReduceColorsModifier;
use 
InterventionImageModifiersRemoveAnimationModifier;
use 
InterventionImageModifiersRemoveProfileModifier;
use 
InterventionImageModifiersResizeCanvasModifier;
use 
InterventionImageModifiersResizeCanvasRelativeModifier;
use 
InterventionImageModifiersResizeDownModifier;
use 
InterventionImageModifiersResizeModifier;
use 
InterventionImageModifiersResolutionModifier;
use 
InterventionImageModifiersRotateModifier;
use 
InterventionImageModifiersScaleDownModifier;
use 
InterventionImageModifiersScaleModifier;
use 
InterventionImageModifiersSharpenModifier;
use 
InterventionImageModifiersSliceAnimationModifier;
use 
InterventionImageModifiersTextModifier;
use 
InterventionImageModifiersTrimModifier;
use 
InterventionImageTypographyFontFactory;
use 
Throwable;
use 
Traversable;

final class 
Image implements ImageInterface
{
    
/**
     * Origin containing the source from which the image was originally created.
     */
    
private OriginInterface $origin;

    
/**
     * Exif data of the current image.
     */
    
private CollectionInterface $exif;

    
/**
     * Create new instance.
     */
    
public function __construct(
        private 
DriverInterface $driver,
        private 
CoreInterface $core,
    ) {
        
$this->origin = new Origin();
        
$this->exif = new Collection();
    }

    
/**
     * {@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(): OriginInterface
    
{
        return 
$this->origin;
    }

    
/**
     * {@inheritdoc}
     *
     * @see ImageInterface::setOrigin()
     */
    
public function setOrigin(OriginInterface $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()
     *
     * @throws InvalidArgumentException
     * @throws ModifierException
     */
    
public function removeAnimation(int|string $position 0): ImageInterface
    
{
        return 
$this->modify(new RemoveAnimationModifier($position));
    }

    
/**
     * {@inheritdoc}
     *
     * @see ImageInterface::sliceAnimation()
     *
     * @throws InvalidArgumentException
     * @throws ModifierException
     */
    
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()
     *
     * @throws ModifierException
     */
    
public function modify(ModifierInterface $modifier): ImageInterface
    
{
        return 
$this->driver()->specializeModifier($modifier)->apply($this);
    }

    
/**
     * {@inheritdoc}
     *
     * @see ImageInterface::analyze()
     *
     * @throws AnalyzerException
     */
    
public function analyze(AnalyzerInterface $analyzer): mixed
    
{
        return 
$this->driver()->specializeAnalyzer($analyzer)->analyze($this);
    }

    
/**
     * {@inheritdoc}
     *
     * @see ImageInterface::save()
     *
     * @throws InvalidArgumentException
     * @throws EncoderException
     * @throws DirectoryNotFoundException
     * @throws FileNotWritableException
     * @throws StreamException
     * @throws NotSupportedException
     */
    
public function save(?string $path nullmixed ...$options): ImageInterface
    
{
        if (
$path === '') {
            throw new 
InvalidArgumentException('Argument $path must not be an empty string');
        }

        if (
is_null($path) && is_null($this->origin()->filePath())) {
            throw new 
EncoderException('Unable to determine path for saving');
        }

        
$path is_null($path) ? $this->origin()->filePath() : $path;

        try {
            
// try to determine encoding format by file extension of the path
            
$encoded $this->encode(new FilePathEncoder($path, ...$options));
        } catch (
EncoderException) {
            
// fallback to encoding format by media type
            
$encoded $this->encode(new MediaTypeEncoder(null, ...$options));
        }

        
$encoded->save($path);

        return 
$this;
    }

    
/**
     * {@inheritdoc}
     *
     * @see ImageInterface::width()
     *
     * @throws AnalyzerException
     */
    
public function width(): int
    
{
        return 
$this->analyze(new WidthAnalyzer());
    }

    
/**
     * {@inheritdoc}
     *
     * @see ImageInterface::height()
     *
     * @throws AnalyzerException
     */
    
public function height(): int
    
{
        return 
$this->analyze(new HeightAnalyzer());
    }

    
/**
     * {@inheritdoc}
     *
     * @see ImageInterface::size()
     *
     * @throws AnalyzerException
     */
    
public function size(): SizeInterface
    
{
        try {
            return new 
Size($this->width(), $this->height());
        } catch (
InvalidArgumentException $e) {
            throw new 
AnalyzerException('Failed to read image size'previous$e);
        }
    }

    
/**
     * {@inheritdoc}
     *
     * @see ImageInterface::colorspace()
     *
     * @throws AnalyzerException
     */
    
public function colorspace(): ColorspaceInterface
    
{
        return 
$this->analyze(new ColorspaceAnalyzer());
    }

    
/**
     * {@inheritdoc}
     *
     * @see ImageInterface::setColorspace()
     *
     * @throws ModifierException
     * @throws NotSupportedException
     */
    
public function setColorspace(string|ColorspaceInterface $colorspace): ImageInterface
    
{
        return 
$this->modify(new ColorspaceModifier($colorspace));
    }

    
/**
     * {@inheritdoc}
     *
     * @see ImageInterface::resolution()
     *
     * @throws AnalyzerException
     */
    
public function resolution(): ResolutionInterface
    
{
        return 
$this->analyze(new ResolutionAnalyzer());
    }

    
/**
     * {@inheritdoc}
     *
     * @see ImageInterface::setResolution()
     *
     * @throws ModifierException
     */
    
public function setResolution(float $xfloat $y): ImageInterface
    
{
        return 
$this->modify(new ResolutionModifier($x$y));
    }

    
/**
     * {@inheritdoc}
     *
     * @see ImageInterface::colorAt()
     *
     * @throws AnalyzerException
     */
    
public function colorAt(int $xint $yint $frame 0): ColorInterface
    
{
        return 
$this->analyze(new PixelColorAnalyzer($x$y$frame));
    }

    
/**
     * {@inheritdoc}
     *
     * @see ImageInterface::colorsAt()
     *
     * @throws AnalyzerException
     */
    
public function colorsAt(int $xint $y): CollectionInterface
    
{
        return 
$this->analyze(new PixelColorsAnalyzer($x$y));
    }

    
/**
     * {@inheritdoc}
     *
     * @see ImageInterface::backgroundColor()
     *
     * @throws ColorDecoderException
     */
    
public function backgroundColor(): ColorInterface
    
{
        return 
$this->driver()->decodeColor(
            
$this->driver()->config()->backgroundColor,
        );
    }

    
/**
     * {@inheritdoc}
     *
     * @see ImageInterface::setBackgroundColor()
     *
     * @throws InvalidArgumentException
     * @throws ColorDecoderException
     */
    
public function setBackgroundColor(string|ColorInterface $color): ImageInterface
    
{
        
$this->driver()->config()->setOptions(
            
backgroundColor$this->driver()->decodeColor($color),
        );

        return 
$this;
    }

    
/**
     * {@inheritdoc}
     *
     * @see ImageInterface::profile()
     *
     * @throws AnalyzerException
     */
    
public function profile(): ProfileInterface
    
{
        return 
$this->analyze(new ProfileAnalyzer());
    }

    
/**
     * {@inheritdoc}
     *
     * @see ImageInterface::setProfile()
     *
     * @throws ModifierException
     */
    
public function setProfile(ProfileInterface $profile): ImageInterface
    
{
        return 
$this->modify(new ProfileModifier($profile));
    }

    
/**
     * {@inheritdoc}
     *
     * @see ImageInterface::removeProfile()
     *
     * @throws ModifierException
     */
    
public function removeProfile(): ImageInterface
    
{
        return 
$this->modify(new RemoveProfileModifier());
    }

    
/**
     * {@inheritdoc}
     *
     * @see ImageInterface::reduceColors()
     *
     * @throws InvalidArgumentException
     * @throws ModifierException
     */
    
public function reduceColors(int $limitnull|string|ColorInterface $background null): ImageInterface
    
{
        return 
$this->modify(new ReduceColorsModifier($limit$background));
    }

    
/**
     * {@inheritdoc}
     *
     * @see ImageInterface::sharpen()
     *
     * @throws InvalidArgumentException
     * @throws ModifierException
     */
    
public function sharpen(int $level 10): ImageInterface
    
{
        return 
$this->modify(new SharpenModifier($level));
    }

    
/**
     * {@inheritdoc}
     *
     * @see ImageInterface::invert()
     *
     * @throws ModifierException
     */
    
public function invert(): ImageInterface
    
{
        return 
$this->modify(new InvertModifier());
    }

    
/**
     * {@inheritdoc}
     *
     * @see ImageInterface::pixelate()
     *
     * @throws InvalidArgumentException
     * @throws ModifierException
     */
    
public function pixelate(int $size): ImageInterface
    
{
        return 
$this->modify(new PixelateModifier($size));
    }

    
/**
     * {@inheritdoc}
     *
     * @see ImageInterface::grayscale()
     *
     * @throws ModifierException
     */
    
public function grayscale(): ImageInterface
    
{
        return 
$this->modify(new GrayscaleModifier());
    }

    
/**
     * {@inheritdoc}
     *
     * @see ImageInterface::brightness()
     *
     * @throws ModifierException
     */
    
public function brightness(int $level): ImageInterface
    
{
        return 
$this->modify(new BrightnessModifier($level));
    }

    
/**
     * {@inheritdoc}
     *
     * @see ImageInterface::contrast()
     *
     * @throws ModifierException
     */
    
public function contrast(int $level): ImageInterface
    
{
        return 
$this->modify(new ContrastModifier($level));
    }

    
/**
     * {@inheritdoc}
     *
     * @see ImageInterface::gamma()
     *
     * @throws ModifierException
     */
    
public function gamma(float $gamma): ImageInterface
    
{
        return 
$this->modify(new GammaModifier($gamma));
    }

    
/**
     * {@inheritdoc}
     *
     * @see ImageInterface::colorize()
     *
     * @throws InvalidArgumentException
     * @throws ModifierException
     */
    
public function colorize(int $red 0int $green 0int $blue 0): ImageInterface
    
{
        return 
$this->modify(new ColorizeModifier($red$green$blue));
    }

    
/**
     * {@inheritdoc}
     *
     * @see ImageInterface::flip()
     *
     * @throws ModifierException
     */
    
public function flip(Direction $direction Direction::HORIZONTAL): ImageInterface
    
{
        return 
$this->modify(new FlipModifier($direction));
    }

    
/**
     * {@inheritdoc}
     *
     * @see ImageInterface::blur()
     *
     * @throws InvalidArgumentException
     * @throws ModifierException
     */
    
public function blur(int $level 5): ImageInterface
    
{
        return 
$this->modify(new BlurModifier($level));
    }

    
/**
     * {@inheritdoc}
     *
     * @see ImageInterface::rotate()
     *
     * @throws InvalidArgumentException
     * @throws ColorDecoderException
     * @throws ModifierException
     */
    
public function rotate(float $anglenull|string|ColorInterface $background null): ImageInterface
    
{
        return 
$this->modify(new RotateModifier($angle$background));
    }

    
/**
     * {@inheritdoc}
     *
     * @see ImageInterface::orient()
     *
     * @throws ModifierException
     */
    
public function orient(): ImageInterface
    
{
        return 
$this->modify(new OrientModifier());
    }

    
/**
     * {@inheritdoc}
     *
     * @see ImageInterface::text()
     *
     * @throws InvalidArgumentException
     * @throws ModifierException
     * @throws StateException
     */
    
public function text(string $textint $xint $y, callable|FontInterface $font): ImageInterface
    
{
        return 
$this->modify(
            new 
TextModifier(
                
$text,
                new 
Point($x$y),
                
FontFactory::build($font),
            ),
        );
    }

    
/**
     * {@inheritdoc}
     *
     * @see ImageInterface::resize()
     *
     * @throws InvalidArgumentException
     * @throws ModifierException
     */
    
public function resize(null|int|Fraction $width nullnull|int|Fraction $height null): ImageInterface
    
{
        try {
            return 
$this->modify(new ResizeModifier(...$this->resolveDimension($width$height)));
        } catch (
AnalyzerException $e) {
            throw new 
ModifierException('Failed to resize image'previous$e);
        }
    }

    
/**
     * {@inheritdoc}
     *
     * @see ImageInterface::resizeDown()
     *
     * @throws InvalidArgumentException
     * @throws ModifierException
     */
    
public function resizeDown(null|int|Fraction $width nullnull|int|Fraction $height null): ImageInterface
    
{
        try {
            return 
$this->modify(new ResizeDownModifier(...$this->resolveDimension($width$height)));
        } catch (
AnalyzerException $e) {
            throw new 
ModifierException('Failed to resize image'previous$e);
        }
    }

    
/**
     * {@inheritdoc}
     *
     * @see ImageInterface::scale()
     *
     * @throws InvalidArgumentException
     * @throws ModifierException
     */
    
public function scale(null|int|Fraction $width nullnull|int|Fraction $height null): ImageInterface
    
{
        try {
            return 
$this->modify(new ScaleModifier(...$this->resolveDimension($width$height)));
        } catch (
AnalyzerException $e) {
            throw new 
ModifierException('Failed to resize image'previous$e);
        }
    }

    
/**
     * {@inheritdoc}
     *
     * @see ImageInterface::scaleDown()
     *
     * @throws InvalidArgumentException
     * @throws ModifierException
     */
    
public function scaleDown(null|int|Fraction $width nullnull|int|Fraction $height null): ImageInterface
    
{
        try {
            return 
$this->modify(new ScaleDownModifier(...$this->resolveDimension($width$height)));
        } catch (
AnalyzerException $e) {
            throw new 
ModifierException('Failed to resize image'previous$e);
        }
    }

    
/**
     * {@inheritdoc}
     *
     * @see ImageInterface::cover()
     *
     * @throws InvalidArgumentException
     * @throws ModifierException
     */
    
public function cover(
        
int|Fraction $width,
        
int|Fraction $height,
        
string|Alignment $alignment Alignment::CENTER,
    ): 
ImageInterface {
        try {
            return 
$this->modify(new CoverModifier(...[
                ...
$this->resolveDimension($width$height),
                ...[
'alignment' => $alignment],
            ]));
        } catch (
AnalyzerException $e) {
            throw new 
ModifierException('Failed to resize image'previous$e);
        }
    }

    
/**
     * {@inheritdoc}
     *
     * @see ImageInterface::coverDown()
     *
     * @throws InvalidArgumentException
     * @throws ModifierException
     */
    
public function coverDown(
        
int|Fraction $width,
        
int|Fraction $height,
        
string|Alignment $alignment Alignment::CENTER,
    ): 
ImageInterface {
        try {
            return 
$this->modify(new CoverDownModifier(...[
                ...
$this->resolveDimension($width$height),
                ...[
'alignment' => $alignment],
            ]));
        } catch (
AnalyzerException $e) {
            throw new 
ModifierException('Failed to resize image'previous$e);
        }
    }

    
/**
     * {@inheritdoc}
     *
     * @see ImageInterface::resizeCanvas()
     *
     * @throws InvalidArgumentException
     * @throws ModifierException
     */
    
public function resizeCanvas(
        
null|int|Fraction $width null,
        
null|int|Fraction $height null,
        
null|string|ColorInterface $background null,
        
string|Alignment $alignment Alignment::CENTER,
    ): 
ImageInterface {
        try {
            return 
$this->modify(new ResizeCanvasModifier(...[
                ...
$this->resolveDimension($width$height),
                ...[
                    
'background' => $background,
                    
'alignment' => $alignment,
                ],
            ]));
        } catch (
AnalyzerException $e) {
            throw new 
ModifierException('Failed to resize image'previous$e);
        }
    }

    
/**
     * {@inheritdoc}
     *
     * @see ImageInterface::resizeCanvasRelative()
     *
     * @throws InvalidArgumentException
     * @throws ModifierException
     */
    
public function resizeCanvasRelative(
        
null|int|Fraction $width null,
        
null|int|Fraction $height null,
        
null|string|ColorInterface $background null,
        
string|Alignment $alignment Alignment::CENTER,
    ): 
ImageInterface {
        try {
            return 
$this->modify(new ResizeCanvasRelativeModifier(...[
                ...
$this->resolveDimension($width$height),
                ...[
                    
'background' => $background,
                    
'alignment' => $alignment,
                ],
            ]));
        } catch (
AnalyzerException $e) {
            throw new 
ModifierException('Failed to resize image'previous$e);
        }
    }

    
/**
     * {@inheritdoc}
     *
     * @see ImageInterface::containDown()
     *
     * @throws InvalidArgumentException
     * @throws ModifierException
     */
    
public function containDown(
        
int|Fraction $width,
        
int|Fraction $height,
        
null|string|ColorInterface $background null,
        
string|Alignment $alignment Alignment::CENTER,
    ): 
ImageInterface {
        try {
            return 
$this->modify(new ContainDownModifier(...[
                ...
$this->resolveDimension($width$height),
                ...[
                    
'background' => $background,
                    
'alignment' => $alignment,
                ],
            ]));
        } catch (
AnalyzerException $e) {
            throw new 
ModifierException('Failed to resize image'previous$e);
        }
    }

    
/**
     * {@inheritdoc}
     *
     * @see ImageInterface::contain()
     *
     * @throws InvalidArgumentException
     * @throws ModifierException
     */
    
public function contain(
        
int|Fraction $width,
        
int|Fraction $height,
        
null|string|ColorInterface $background null,
        
string|Alignment $alignment Alignment::CENTER,
    ): 
ImageInterface {
        try {
            return 
$this->modify(new ContainModifier(...[
                ...
$this->resolveDimension($width$height),
                ...[
                    
'background' => $background,
                    
'alignment' => $alignment,
                ],
            ]));
        } catch (
AnalyzerException $e) {
            throw new 
ModifierException('Failed to resize image'previous$e);
        }
    }

    
/**
     * {@inheritdoc}
     *
     * @see ImageInterface::crop()
     *
     * @throws InvalidArgumentException
     * @throws ModifierException
     */
    
public function crop(
        
int|Fraction $width,
        
int|Fraction $height,
        
int $x 0,
        
int $y 0,
        
null|string|ColorInterface $background null,
        
string|Alignment $alignment Alignment::TOP_LEFT,
    ): 
ImageInterface {
        try {
            return 
$this->modify(new CropModifier(...[
                ...
$this->resolveDimension($width$height),
                ...[
                    
'x' => $x,
                    
'y' => $y,
                    
'background' => $background,
                    
'alignment' => $alignment,
                ],
            ]));
        } catch (
AnalyzerException $e) {
            throw new 
ModifierException('Failed to resize image'previous$e);
        }
    }

    
/**
     * {@inheritdoc}
     *
     * @see ImageInterface::trim()
     *
     * @throws InvalidArgumentException
     * @throws ModifierException
     */
    
public function trim(int $tolerance 0): ImageInterface
    
{
        return 
$this->modify(new TrimModifier($tolerance));
    }

    
/**
     * {@inheritdoc}
     *
     * @see ImageInterface::insert()
     *
     * @throws InvalidArgumentException
     * @throws ModifierException
     */
    
public function insert(
        
mixed $image,
        
int $x 0,
        
int $y 0,
        
string|Alignment $alignment Alignment::TOP_LEFT,
        
float $transparency 1,
    ): 
ImageInterface {
        return 
$this->modify(new InsertModifier($image$x$y$alignment$transparency));
    }

    
/**
     * {@inheritdoc}
     *
     * @see ImageInterface::fill()
     *
     * @throws ModifierException
     */
    
public function fill(string|ColorInterface $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::fillTransparentAreas()
     *
     * @throws ModifierException
     */
    
public function fillTransparentAreas(null|string|ColorInterface $color null): ImageInterface
    
{
        return 
$this->modify(new FillTransparentAreasModifier($color));
    }

    
/**
     * {@inheritdoc}
     *
     * @see ImageInterface::drawPixel()
     *
     * @throws ModifierException
     * @throws ColorDecoderException
     */
    
public function drawPixel(int $xint $ystring|ColorInterface $color): ImageInterface
    
{
        return 
$this->modify(new DrawPixelModifier(new Point($x$y), $color));
    }

    
/**
     * {@inheritdoc}
     *
     * @see ImageInterface::drawRectangle()
     *
     * @throws InvalidArgumentException
     * @throws ModifierException
     * @throws ColorDecoderException
     */
    
public function drawRectangle(callable|Rectangle $rectangle): ImageInterface
    
{
        return 
$this->modify(
            new 
DrawRectangleModifier(
                
RectangleFactory::build($rectangle),
            ),
        );
    }

    
/**
     * {@inheritdoc}
     *
     * @see ImageInterface::drawEllipse()
     *
     * @throws ModifierException
     * @throws ColorDecoderException
     */
    
public function drawEllipse(callable|Ellipse $ellipse): ImageInterface
    
{
        return 
$this->modify(
            new 
DrawEllipseModifier(
                
EllipseFactory::build($ellipse),
            ),
        );
    }

    
/**
     * {@inheritdoc}
     *
     * @see ImageInterface::drawCircle()
     *
     * @throws ModifierException
     * @throws ColorDecoderException
     */
    
public function drawCircle(callable|Circle $circle): ImageInterface
    
{
        return 
$this->modify(
            new 
DrawEllipseModifier(
                
CircleFactory::build($circle),
            ),
        );
    }

    
/**
     * {@inheritdoc}
     *
     * @see ImageInterface::drawPolygon()
     *
     * @throws InvalidArgumentException
     * @throws ModifierException
     * @throws ColorDecoderException
     */
    
public function drawPolygon(callable|Polygon $polygon): ImageInterface
    
{
        return 
$this->modify(
            new 
DrawPolygonModifier(
                
PolygonFactory::build($polygon),
            ),
        );
    }

    
/**
     * {@inheritdoc}
     *
     * @see ImageInterface::drawLine()
     *
     * @throws ModifierException
     * @throws ColorDecoderException
     */
    
public function drawLine(callable|Line $line): ImageInterface
    
{
        return 
$this->modify(
            new 
DrawLineModifier(
                
LineFactory::build($line),
            ),
        );
    }

    
/**
     * {@inheritdoc}
     *
     * @see ImageInterface::drawBezier()
     *
     * @throws ModifierException
     * @throws ColorDecoderException
     */
    
public function drawBezier(callable|Bezier $bezier): ImageInterface
    
{
        return 
$this->modify(
            new 
DrawBezierModifier(
                
BezierFactory::build($bezier),
            ),
        );
    }

    
/**
     * {@inheritdoc}
     *
     * @see ImageInterface::draw()
     *
     * @throws InvalidArgumentException
     * @throws NotSupportedException
     * @throws ModifierException
     * @throws ColorDecoderException
     */
    
public function draw(DrawableInterface $drawable): ImageInterface
    
{
        return 
$this->modify(match ($drawable::class) {
            
Rectangle::class => new DrawRectangleModifier($drawable),
            
Circle::class, Ellipse::class => new DrawEllipseModifier($drawable),
            
Bezier::class => new DrawBezierModifier($drawable),
            
Line::class => new DrawLineModifier($drawable),
            
Polygon::class => new DrawPolygonModifier($drawable),
            default => throw new 
NotSupportedException('No modifier for ' $drawable::class . ' found'),
        });
    }

    
/**
     * {@inheritdoc}
     *
     * @see ImageInterface::encode()
     *
     * @throws EncoderException
     */
    
public function encode(?EncoderInterface $encoder null): EncodedImageInterface
    
{
        return 
$this->driver()->specializeEncoder(
            
$encoder ?: new AutoEncoder(),
        )->
encode($this);
    }

    
/**
     * {@inheritdoc}
     *
     * @see ImageInterface::encodeUsingFormat()
     *
     * @throws EncoderException
     */
    
public function encodeUsingFormat(Format $formatmixed ...$options): EncodedImageInterface
    
{
        return 
$this->encode(new FormatEncoder($format, ...$options));
    }

    
/**
     * {@inheritdoc}
     *
     * @see ImageInterface::encodeUsingMediaType()
     *
     * @throws EncoderException
     */
    
public function encodeUsingMediaType(string|MediaType $mediaTypemixed ...$options): EncodedImageInterface
    
{
        return 
$this->encode(new MediaTypeEncoder($mediaType, ...$options));
    }

    
/**
     * {@inheritdoc}
     *
     * @see ImageInterface::encodeUsingFileExtension()
     *
     * @throws InvalidArgumentException
     * @throws NotSupportedException
     * @throws EncoderException
     */
    
public function encodeUsingFileExtension(
        
string|FileExtension $fileExtension,
        
mixed ...$options,
    ): 
EncodedImageInterface {
        return 
$this->encode(new FileExtensionEncoder($fileExtension, ...$options));
    }

    
/**
     * {@inheritdoc}
     *
     * @see ImageInterface::encodeUsingPath()
     *
     * @throws InvalidArgumentException
     * @throws NotSupportedException
     * @throws EncoderException
     */
    
public function encodeUsingPath(string $pathmixed ...$options,): EncodedImageInterface
    
{
        return 
$this->encode(new FilePathEncoder($path, ...$options));
    }

    
/**
     * Build resizing dimension from various inputs including fractions based lengths.
     *
     * @throws InvalidArgumentException
     * @throws AnalyzerException
     * @return array{'width': ?int, 'height': ?int}
     */
    
private function resolveDimension(null|int|Fraction $widthnull|int|Fraction $height): array
    {
        if (
$width instanceof Fraction || $height instanceof Fraction) {
            
$size $this->size();
            
$width = ($width instanceof Fraction) ? (int) round($width->of($size->width())) : $width;
            
$height = ($height instanceof Fraction) ? (int) round($height->of($size->height())) : $height;
        }

        return [
            
'width' => $width,
            
'height' => $height,
        ];
    }

    
/**
     * Show debug info for the current image.
     *
     * @return array<string, ?int>
     */
    
public function __debugInfo(): array
    {
        try {
            return [
                
'width' => $this->width(),
                
'height' => $this->height(),
            ];
        } catch (
Throwable) {
            return [
                
'width' => null,
                
'height' => null,
            ];
        }
    }

    
/**
     * Clone image.
     */
    
public function __clone(): void
    
{
        
$this->driver = clone $this->driver;
        
$this->core = clone $this->core;
        
$this->exif = clone $this->exif;
    }
}
Онлайн: 1
Реклама