stil/gif-endec

此包已被弃用且不再维护。没有建议的替代包。

PHP GIF 解码器和带有回调函数的解码器。

v0.2.0 2016-10-14 23:11 UTC

This package is not auto-updated.

Last update: 2021-02-19 21:31:18 UTC


README

这是什么?

gif-endec 是一个 GIF 编码器和解码器。它允许您将动画 GIF 分割成单独的帧。您还可以提取帧持续时间和处置方法(处置方法指示图形显示后的处理方式)。

性能

由于一些代码优化,这个库解码动画 GIF 比Sybio/GifFrameExtractor快得多。它还优化了内存使用,允许您逐个处理解码帧。它不会一次性将所有帧加载到内存中。

安装

使用 Composer 安装此包。

composer require stil/gif-endec

分割动画 GIF 为帧

在这个示例中,我们将分割这个动画 GIF 为单独的帧。

<?php
require __DIR__ . '/../vendor/autoload.php';

use GIFEndec\Events\FrameDecodedEvent;
use GIFEndec\IO\FileStream;
use GIFEndec\Decoder;

/**
 * Open GIF as FileStream
 */
$gifStream = new FileStream("path/to/animation.gif");

/**
 * Create Decoder instance from MemoryStream
 */
$gifDecoder = new Decoder($gifStream);

/**
 * Run decoder. Pass callback function to process decoded Frames when they're ready.
 */
$gifDecoder->decode(function (FrameDecodedEvent $event) {
    /**
     * Convert frame index to zero-padded strings (001, 002, 003)
     */
    $paddedIndex = str_pad($event->frameIndex, 3, '0', STR_PAD_LEFT);

    /**
     * Write frame images to directory
     */
    $event->decodedFrame->getStream()->copyContentsToFile(
        __DIR__ . "/frames/frame{$paddedIndex}.gif"
    );
    // Or get binary data as string:
    // $frame->getStream()->getContents()

    /**
     * You can access frame duration using Frame::getDuration() method, ex.:
     */
    echo $event->decodedFrame->getDuration() . "\n";
});

结果帧将写入到目录:

渲染动画 GIF 的帧

如果您的 GIF 使用了透明度保存,一些帧可能看起来像这样:

在以下示例中,您将看到如何渲染 GIF 帧。

<?php
require __DIR__ . '/../vendor/autoload.php';

use GIFEndec\Events\FrameRenderedEvent;
use GIFEndec\IO\FileStream;
use GIFEndec\Decoder;
use GIFEndec\Renderer;

/**
 * Open GIF as FileStream
 */
$gifStream = new FileStream("path/to/animation.gif");

/**
 * Create Decoder instance from MemoryStream
 */
$gifDecoder = new Decoder($gifStream);

/**
 * Create Renderer instance
 */
$gifRenderer = new Renderer($gifDecoder);

/**
 * Run decoder. Pass callback function to process decoded Frames when they're ready.
 */
$gifRenderer->start(function (FrameRenderedEvent $event) {
    /**
     * $gdResource is a GD image resource. See https://php.ac.cn/manual/en/book.image.php
     */

    /**
     * Write frame images to directory
     */
    imagepng($event->renderedFrame, __DIR__ . "/frames/frame{$event->frameIndex}.png");
});

创建动画

假设现在,我们想将这个滑板动画速度放慢一点,以便我们可以看到如何完成这样的特技。我们已经在 skateboarder/frame*.gif 目录中分割了帧。

<?php
use GIFEndec\Color;
use GIFEndec\Encoder;
use GIFEndec\Frame;
use GIFEndec\IO\FileStream;

$gif = new Encoder();

foreach (glob('skateboarder/frame*.gif') as $file) {
    $stream = new FileStream($file);
    $frame = new Frame();
    $frame->setDisposalMethod(1);
    $frame->setStream($stream);
    $frame->setDuration(30); // 0.30s
    $frame->setTransparentColor(new Color(255, 255, 255));
    $gif->addFrame($frame);
}

$gif->addFooter(); // Required after you're done with adding frames

// Copy result animation to file
$gif->getStream()->copyContentsToFile('skateboarder/animation.gif');

这是放慢后的动画看起来会像这样:

处置方法解释

处置方法指示图形显示后的处理方式。

Values :    0 -   No disposal specified. The decoder is
                  not required to take any action.
            1 -   Do not dispose. The graphic is to be left
                  in place.
            2 -   Restore to background color. The area used by the
                  graphic must be restored to the background color.
            3 -   Restore to previous. The decoder is required to
                  restore the area overwritten by the graphic with
                  what was there prior to rendering the graphic.
         4-7 -    To be defined.

来源: http://www.w3.org/Graphics/GIF/spec-gif89a.txt