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

declare(strict_types=1);

namespace 
InterventionGif;

use 
ArrayIterator;
use 
GdImage;
use 
InterventionGifExceptionsEncoderException;
use 
IteratorAggregate;
use 
Traversable;

/**
 * @implements IteratorAggregate<GifDataStream>
 */
class Splitter implements IteratorAggregate
{
    
/**
     * Single frames resolved to GifDataStream
     *
     * @var array<GifDataStream>
     */
    
protected array $frames = [];

    
/**
     * Delays of each frame
     *
     * @var array<int>
     */
    
protected array $delays = [];

    
/**
     * Create new instance
     *
     * @param GifDataStream $stream
     */
    
public function __construct(protected GifDataStream $stream)
    {
        
//
    
}

    
/**
     * Iterator
     *
     * @return Traversable<GifDataStream>
     */
    
public function getIterator(): Traversable
    
{
        return new 
ArrayIterator($this->frames);
    }

    
/**
     * Get frames
     *
     * @return array<GifDataStream>
     */
    
public function getFrames(): array
    {
        return 
$this->frames;
    }

    
/**
     * Get delays
     *
     * @return array<int>
     */
    
public function getDelays(): array
    {
        return 
$this->delays;
    }

    
/**
     * Set stream of instance
     *
     * @param GifDataStream $stream
     */
    
public function setStream(GifDataStream $stream): self
    
{
        
$this->stream $stream;

        return 
$this;
    }

    
/**
     * Static constructor method
     *
     * @param GifDataStream $stream
     * @return Splitter
     */
    
public static function create(GifDataStream $stream): self
    
{
        return new 
self($stream);
    }

    
/**
     * Split current stream into array of seperate streams for each frame
     *
     * @return Splitter
     */
    
public function split(): self
    
{
        
$this->frames = [];

        foreach (
$this->stream->getFrames() as $frame) {
            
// create separate stream for each frame
            
$gif Builder::canvas(
                
$this->stream->getLogicalScreenDescriptor()->getWidth(),
                
$this->stream->getLogicalScreenDescriptor()->getHeight()
            )->
getGifDataStream();

            
// check if working stream has global color table
            
if ($this->stream->hasGlobalColorTable()) {
                
$gif->setGlobalColorTable($this->stream->getGlobalColorTable());
                
$gif->getLogicalScreenDescriptor()->setGlobalColorTableExistance(true);

                
$gif->getLogicalScreenDescriptor()->setGlobalColorTableSorted(
                    
$this->stream->getLogicalScreenDescriptor()->getGlobalColorTableSorted()
                );

                
$gif->getLogicalScreenDescriptor()->setGlobalColorTableSize(
                    
$this->stream->getLogicalScreenDescriptor()->getGlobalColorTableSize()
                );

                
$gif->getLogicalScreenDescriptor()->setBackgroundColorIndex(
                    
$this->stream->getLogicalScreenDescriptor()->getBackgroundColorIndex()
                );

                
$gif->getLogicalScreenDescriptor()->setPixelAspectRatio(
                    
$this->stream->getLogicalScreenDescriptor()->getPixelAspectRatio()
                );

                
$gif->getLogicalScreenDescriptor()->setBitsPerPixel(
                    
$this->stream->getLogicalScreenDescriptor()->getBitsPerPixel()
                );
            }

            
// copy original frame
            
$gif->addFrame($frame);

            
$this->frames[] = $gif;
            
$this->delays[] = match (is_object($frame->getGraphicControlExtension())) {
                
true => $frame->getGraphicControlExtension()->getDelay(),
                default => 
0,
            };
        }

        return 
$this;
    }

    
/**
     * Return array of GD library resources for each frame
     *
     * @throws EncoderException
     * @return array<GdImage>
     */
    
public function toResources(): array
    {
        
$resources = [];

        foreach (
$this->frames as $frame) {
            
$resource imagecreatefromstring($frame->encode());
            
imagepalettetotruecolor($resource);
            
imagesavealpha($resourcetrue);
            
$resources[] = $resource;
        }

        return 
$resources;
    }

    
/**
     * Return array of coalesced GD library resources for each frame
     *
     * @throws EncoderException
     * @return array<GdImage>
     */
    
public function coalesceToResources(): array
    {
        
$resources $this->toResources();

        
// static gif files don't need to be coalesced
        
if (count($resources) === 1) {
            return 
$resources;
        }

        
$width imagesx($resources[0]);
        
$height imagesy($resources[0]);
        
$transparent imagecolortransparent($resources[0]);

        foreach (
$resources as $key => $resource) {
            
// get meta data
            
$gif $this->frames[$key];
            
$descriptor $gif->getFirstFrame()->getImageDescriptor();
            
$offset_x $descriptor->getLeft();
            
$offset_y $descriptor->getTop();
            
$w $descriptor->getWidth();
            
$h $descriptor->getHeight();

            if (
in_array($this->getDisposalMethod($gif), [DisposalMethod::NONEDisposalMethod::PREVIOUS])) {
                if (
$key >= 1) {
                    
// create normalized gd image
                    
$canvas imagecreatetruecolor($width$height);
                    if (
imagecolortransparent($resource) != -1) {
                        
$transparent imagecolortransparent($resource);
                    } else {
                        
$transparent imagecolorallocatealpha($resource2550255127);
                    }

                    
// fill with transparent
                    
imagefill($canvas00$transparent);
                    
imagecolortransparent($canvas$transparent);
                    
imagealphablending($canvastrue);

                    
// insert last as base
                    
imagecopy(
                        
$canvas,
                        
$resources[$key 1],
                        
0,
                        
0,
                        
0,
                        
0,
                        
$width,
                        
$height
                    
);

                    
// insert resource
                    
imagecopy(
                        
$canvas,
                        
$resource,
                        
$offset_x,
                        
$offset_y,
                        
0,
                        
0,
                        
$w,
                        
$h
                    
);
                } else {
                    
imagealphablending($resourcetrue);
                    
$canvas $resource;
                }
            } else {
                
// create normalized gd image
                
$canvas imagecreatetruecolor($width$height);
                if (
imagecolortransparent($resource) != -1) {
                    
$transparent imagecolortransparent($resource);
                } else {
                    
$transparent imagecolorallocatealpha($resource2550255127);
                }

                
// fill with transparent
                
imagefill($canvas00$transparent);
                
imagecolortransparent($canvas$transparent);
                
imagealphablending($canvastrue);

                
// insert frame resource
                
imagecopy(
                    
$canvas,
                    
$resource,
                    
$offset_x,
                    
$offset_y,
                    
0,
                    
0,
                    
$w,
                    
$h
                
);
            }

            
$resources[$key] = $canvas;
        }

        return 
$resources;
    }

    
/**
     * Find and return disposal method of given gif data stream
     *
     * @param GifDataStream $gif
     * @return DisposalMethod
     */
    
private function getDisposalMethod(GifDataStream $gif): DisposalMethod
    
{
        return 
$gif->getFirstFrame()->getGraphicControlExtension()->getDisposalMethod();
    }
}
Онлайн: 0
Реклама