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

declare(strict_types=1);

namespace 
InterventionGif;

use 
Exception;
use 
InterventionGifBlocksFrameBlock;
use 
InterventionGifBlocksGraphicControlExtension;
use 
InterventionGifBlocksImageDescriptor;
use 
InterventionGifBlocksNetscapeApplicationExtension;
use 
InterventionGifBlocksTableBasedImage;
use 
InterventionGifExceptionsDecoderException;
use 
InterventionGifExceptionsEncoderException;
use 
InterventionGifTraitsCanHandleFiles;

class 
Builder
{
    use 
CanHandleFiles;

    
/**
     * Create new instance
     *
     * @param GifDataStream $gif
     * @return void
     */
    
public function __construct(protected GifDataStream $gif = new GifDataStream())
    {
    }

    
/**
     * Get GifDataStream object we're currently building
     *
     * @return GifDataStream
     */
    
public function getGifDataStream(): GifDataStream
    
{
        return 
$this->gif;
    }

    
/**
     * Set canvas size of gif
     *
     * @param int $width
     * @param int $height
     * @return Builder
     */
    
public function setSize(int $widthint $height): self
    
{
        
$this->gif->getLogicalScreenDescriptor()->setSize($width$height);

        return 
$this;
    }

    
/**
     * Create new canvas
     *
     * @param int $width
     * @param int $height
     * @return self
     */
    
public static function canvas(int $widthint $height): self
    
{
        return (new 
self())->setSize($width$height);
    }

    
/**
     * Set loop count
     *
     * @param int $loops
     * @return Builder
     * @throws Exception
     */
    
public function setLoops(int $loops): self
    
{
        if (
$this->gif->getFrames() === []) {
            throw new 
Exception('Add at least one frame before setting the loop count');
        }

        if (
$loops >= 0) {
            
// add frame count to existing or new netscape extension on first frame
            
if (!$this->gif->getFirstFrame()->getNetscapeExtension()) {
                
$this->gif->getFirstFrame()->addApplicationExtension(
                    new 
NetscapeApplicationExtension()
                );
            }
            
$this->gif->getFirstFrame()->getNetscapeExtension()->setLoops($loops);
        }

        return 
$this;
    }

    
/**
     * Create new animation frame from given source
     * which can be path to a file or GIF image data
     *
     * @param string|resource $source
     * @param float $delay time delay in seconds
     * @param int $left position offset in pixels from left
     * @param int $top position offset in pixels from top
     * @param bool $interlaced
     * @throws DecoderException
     * @return Builder
     */
    
public function addFrame(
        
mixed $source,
        
float $delay 0,
        
int $left 0,
        
int $top 0,
        
bool $interlaced false
    
): self {
        
$frame = new FrameBlock();
        
$source Decoder::decode($source);

        
// store delay
        
$frame->setGraphicControlExtension(
            
$this->buildGraphicControlExtension(
                
$source,
                
intval($delay 100)
            )
        );

        
// store image
        
$frame->setTableBasedImage(
            
$this->buildTableBasedImage($source$left$top$interlaced)
        );

        
// add frame
        
$this->gif->addFrame($frame);

        return 
$this;
    }

    
/**
     * Build new graphic control extension with given delay & disposal method
     *
     * @param GifDataStream $source
     * @param int $delay
     * @param DisposalMethod $disposalMethod
     * @return GraphicControlExtension
     */
    
protected function buildGraphicControlExtension(
        
GifDataStream $source,
        
int $delay,
        
DisposalMethod $disposalMethod DisposalMethod::BACKGROUND
    
): GraphicControlExtension {
        
// create extension
        
$extension = new GraphicControlExtension($delay$disposalMethod);

        
// set transparency index
        
$control $source->getFirstFrame()->getGraphicControlExtension();
        if (
$control && $control->getTransparentColorExistance()) {
            
$extension->setTransparentColorExistance();
            
$extension->setTransparentColorIndex(
                
$control->getTransparentColorIndex()
            );
        }

        return 
$extension;
    }

    
/**
     * Build table based image object from given source
     *
     * @param GifDataStream $source
     * @param int $left
     * @param int $top
     * @param bool $interlaced
     * @return TableBasedImage
     */
    
protected function buildTableBasedImage(
        
GifDataStream $source,
        
int $left,
        
int $top,
        
bool $interlaced
    
): TableBasedImage {
        
$block = new TableBasedImage();
        
$block->setImageDescriptor(new ImageDescriptor());

        
// set global color table from source as local color table
        
$block->getImageDescriptor()->setLocalColorTableExistance();
        
$block->setColorTable($source->getGlobalColorTable());

        
$block->getImageDescriptor()->setLocalColorTableSorted(
            
$source->getLogicalScreenDescriptor()->getGlobalColorTableSorted()
        );

        
$block->getImageDescriptor()->setLocalColorTableSize(
            
$source->getLogicalScreenDescriptor()->getGlobalColorTableSize()
        );

        
$block->getImageDescriptor()->setSize(
            
$source->getLogicalScreenDescriptor()->getWidth(),
            
$source->getLogicalScreenDescriptor()->getHeight()
        );

        
// set position
        
$block->getImageDescriptor()->setPosition($left$top);

        
// set interlaced flag
        
$block->getImageDescriptor()->setInterlaced($interlaced);

        
// add image data from source
        
$block->setImageData($source->getFirstFrame()->getImageData());

        return 
$block;
    }

    
/**
     * Encode the current build
     *
     * @throws EncoderException
     * @return string
     */
    
public function encode(): string
    
{
        return 
$this->gif->encode();
    }
}
Онлайн: 1
Реклама