Giter Club home page Giter Club logo

gif-endec's Introduction

Introduction

What is that?

gif-endec is a GIF encoder and decoder. It allows you to split animated GIFs into separate frames. You can also extract frame durations and disposal method (disposal method indicates the way in which the graphic is to be treated after being displayed).

Performance

Thanks to some code optimizations, this library decodes animated GIFs much faster than Sybio/GifFrameExtractor. It also optimizes memory usage, allowing you to process decoded frames one after another. It doesn't load all frames to memory at once.

Installation

Install this package with Composer.

composer require stil/gif-endec

Split animated GIF into frames

In this example we'll split this animated GIF into separate frames.

<?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";
});

The result frames will be written to directory:

Render animated GIFs' frames

If your GIF is saved using transparency, some frames might look like this:

In following example you'll see how to render GIF frames.

<?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 http://php.net/manual/en/book.image.php
     */

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

Create an animation

Assume now, that we want to slow down this skateboarder animation a little bit, so we can see how to make such trick. We already have splitted frames in skateboarder/frame*.gif directory.

<?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');

This is how our slowed down animation would look like:

Disposal methods explained

Disposal Method indicates the way in which the graphic is to be treated after being displayed.

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.

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

gif-endec's People

Contributors

stil avatar kevinruscoe avatar

Watchers

James Cloos avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.