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

declare(strict_types=1);

namespace 
InterventionImageDriversImagick;

use 
Exception;
use 
Imagick;
use 
ImagickException;
use 
InterventionImageCollection;
use 
InterventionImageExceptionsDriverException;
use 
Iterator;
use 
InterventionImageInterfacesCoreInterface;
use 
InterventionImageExceptionsInvalidArgumentException;
use 
InterventionImageExceptionsNotSupportedException;
use 
InterventionImageExceptionsRuntimeException;
use 
InterventionImageExceptionsStateException;
use 
InterventionImageInterfacesCollectionInterface;
use 
InterventionImageInterfacesFrameInterface;

/**
 * @implements Iterator<FrameInterface>
 */
class Core implements CoreInterface, Iterator
{
    protected 
int $iteratorIndex = 0;
    protected 
CollectionInterface $meta;

    
/**
     * Create new core instance
     */
    
public function __construct(protected Imagick $imagick)
    {
        
$this->meta = new Collection();
    }

    
/**
     * {@inheritdoc}
     *
     * @see CollectionInterface::has()
     */
    
public function has(int|string $key): bool
    
{
        try {
            return 
$this->imagick->setIteratorIndex((int) $key);
        } catch (
ImagickException) {
            return 
false;
        }
    }

    
/**
     * {@inheritdoc}
     *
     * @see CollectionInterface::push()
     *
     * @throws DriverException
     */
    
public function push(mixed $item): CollectionInterface
    
{
        return 
$this->add($item);
    }

    
/**
     * {@inheritdoc}
     *
     * @see CoreInterface::map()
     *
     * @throws NotSupportedException
     */
    
public function map(callable $callback): CoreInterface
    
{
        throw new 
NotSupportedException('Not implemented');
    }

    
/**
     * {@inheritdoc}
     *
     * @see CoreInterface::filter()
     *
     * @throws Exception
     */
    
public function filter(callable $callback): CoreInterface
    
{
        throw new 
Exception('Not implemented');
    }

    
/**
     * {@inheritdoc}
     *
     * @see CollectionInterface::get()
     *
     * @throws DriverException
     */
    
public function get(int|string $key, mixed $default = null): mixed
    
{
        try {
            
$this->imagick->setIteratorIndex((int) $key);
        } catch (
ImagickException) {
            return 
$default;
        }

        try {
            return new 
Frame($this->imagick->current());
        } catch (
ImagickException | RuntimeException $e) {
            throw new 
DriverException('Failed to get current frame data', previous: $e);
        }
    }

    
/**
     * {@inheritdoc}
     *
     * @see CollectionInterface::set()
     *
     * @throws DriverException
     */
    
public function set(int|string $key, mixed $item): CollectionInterface
    
{
        return 
$this->add($item);
    }

    
/**
     * {@inheritdoc}
     *
     * @see CollectionInterface::at()
     *
     * @throws DriverException
     */
    
public function at(int $key = 0, mixed $default = null): mixed
    
{
        return 
$this->get($key, $default);
    }

    
/**
     * {@inheritdoc}
     *
     * @see CollectionInterface::clear()
     */
    
public function clear(): CollectionInterface
    
{
        
$this->imagick->clear();

        return 
$this;
    }

    
/**
     * {@inheritdoc}
     *
     * @see CollectionInterface::slice()
     *
     * @throws DriverException
     */
    
public function slice(int $offset, ?int $length = null): CollectionInterface
    
{
        
$length = is_null($length) ? $this->count() : $length;
        
$count = $this->count();

        for (
$i = $count - 1; $i >= 0; $i--) {
            if (
$i < $offset || $i >= $offset + $length) {
                try {
                    
$this->imagick->setIteratorIndex($i);
                    
$this->imagick->removeImage();
                } catch (
ImagickException $e) {
                    throw new 
DriverException('Failed to slice image', previous: $e);
                }
            }
        }

        try {
            
$loops = $this->imagick->getImageIterations();
            
$coalesced = $this->imagick->coalesceImages();
            
$this->imagick->clear();
            
$this->imagick = $coalesced;
            
$this->imagick->setImageIterations($loops);
        } catch (
ImagickException $e) {
            throw new 
DriverException('Failed to slice image', previous: $e);
        }

        return 
$this;
    }

    
/**
     * {@inheritdoc}
     *
     * @see CoreInterface::add()
     *
     * @throws DriverException
     */
    
public function add(FrameInterface $frame): CoreInterface
    
{
        
$imagick = $frame->native();

        try {
            
$imagick->setImageDelay(
                (int) 
round($frame->delay() * 100),
            );

            
$imagick->setImageDispose($frame->disposalMethod());

            
$size = $frame->size();
            
$imagick->setImagePage(
                
$size->width(),
                
$size->height(),
                
$frame->offsetLeft(),
                
$frame->offsetTop(),
            );

            
$this->imagick->addImage($imagick);
        } catch (
ImagickException $e) {
            throw new 
DriverException('Failed to add image frame', previous: $e);
        }

        return 
$this;
    }

    
/**
     * {@inheritdoc}
     *
     * @see CoreInterface::count()
     *
     * @throws DriverException
     */
    
public function count(): int
    
{
        try {
            return 
$this->imagick->getNumberImages();
        } catch (
ImagickException $e) {
            throw new 
DriverException('Failed to count image frames', previous: $e);
        }
    }

    
/**
     * {@inheritdoc}
     *
     * @see Iterator::rewind()
     *
     * @throws DriverException
     */
    
public function current(): mixed
    
{
        try {
            
$this->imagick->setIteratorIndex($this->iteratorIndex);

            return new 
Frame($this->imagick->current());
        } catch (
ImagickException | RuntimeException $e) {
            throw new 
DriverException('Failed to iterate image frames', previous: $e);
        }
    }

    
/**
     * {@inheritdoc}
     *
     * @see Iterator::rewind()
     */
    
public function next(): void
    
{
        
$this->iteratorIndex += 1;
    }

    
/**
     * {@inheritdoc}
     *
     * @see Iterator::rewind()
     */
    
public function key(): mixed
    
{
        return 
$this->iteratorIndex;
    }

    
/**
     * {@inheritdoc}
     *
     * @see Iterator::rewind()
     */
    
public function valid(): bool
    
{
        try {
            
$result = $this->imagick->setIteratorIndex($this->iteratorIndex);
        } catch (
ImagickException) {
            return 
false;
        }

        return 
$result;
    }

    
/**
     * {@inheritdoc}
     *
     * @see Iterator::rewind()
     */
    
public function rewind(): void
    
{
        
$this->iteratorIndex = 0;
    }

    
/**
     * {@inheritdoc}
     *
     * @see CoreInterface::native()
     */
    
public function native(): mixed
    
{
        return 
$this->imagick;
    }

    
/**
     * {@inheritdoc}
     *
     * @see CoreInterface::setNative()
     *
     * @throws InvalidArgumentException
     */
    
public function setNative(mixed $native): CoreInterface
    
{
        if (!
$native instanceof Imagick) {
            throw new 
InvalidArgumentException('Argument $native must be of type ' . Imagick::class);
        }

        
$this->imagick->clear();
        
$this->imagick = $native;

        return 
$this;
    }

    
/**
     * {@inheritdoc}
     *
     * @see CoreInterface::frame()
     *
     * @throws InvalidArgumentException
     * @throws DriverException
     */
    
public function frame(int $position): FrameInterface
    
{
        foreach (
$this->imagick as $core) {
            try {
                if (
$core->getIteratorIndex() === $position) {
                    return new 
Frame($core);
                }
            } catch (
ImagickException | RuntimeException $e) {
                throw new 
DriverException('Failed to load image frame a position ' . $position, previous: $e);
            }
        }

        throw new 
InvalidArgumentException('Frame #' . $position . ' could not be found in the image');
    }

    
/**
     * {@inheritdoc}
     *
     * @see CoreInterface::loops()
     *
     * @throws DriverException
     */
    
public function loops(): int
    
{
        try {
            return 
$this->imagick->getImageIterations();
        } catch (
ImagickException $e) {
            throw new 
DriverException('Failed to get image loop count', previous: $e);
        }
    }

    
/**
     * {@inheritdoc}
     *
     * @see CoreInterface::setLoops()
     *
     * @throws DriverException
     */
    
public function setLoops(int $loops): CoreInterface
    
{
        try {
            
$this->imagick->resetIterator();
            
$this->imagick->setImageIterations($loops);
        } catch (
ImagickException $e) {
            throw new 
DriverException('Failed to set image loop count', previous: $e);
        }

        return 
$this;
    }

    
/**
     * {@inheritdoc}
     *
     * @see CollectionInterface::first()
     *
     * @throws DriverException
     * @throws StateException
     */
    
public function first(): FrameInterface
    
{
        try {
            return 
$this->frame(0);
        } catch (
InvalidArgumentException $e) {
            throw new 
StateException('First frame not found in image', previous: $e);
        }
    }

    
/**
     * {@inheritdoc}
     *
     * @see CollectableInterface::last()
     *
     * @throws DriverException
     * @throws StateException
     */
    
public function last(): FrameInterface
    
{
        try {
            return 
$this->frame($this->count() - 1);
        } catch (
InvalidArgumentException $e) {
            throw new 
StateException('Last frame not found in image', previous: $e);
        }
    }

    
/**
     * {@inheritdoc}
     *
     * @see CoreInterface::meta()
     */
    
public function meta(): CollectionInterface
    
{
        return 
$this->meta;
    }

    
/**
     * {@inheritdoc}
     *
     * @see CollectionInterface::toArray()
     */
    
public function toArray(): array
    {
        
$frames = [];

        foreach (
$this as $frame) {
            
$frames[] = $frame;
        }

        return 
$frames;
    }

    
/**
     * Clone instance
     */
    
public function __clone(): void
    
{
        
$this->meta = clone $this->meta;
        
$this->imagick = clone $this->imagick;
    }
}
Онлайн: 1
Реклама