9

我搜索了很长时间如何使用 PHP 从动画 GIF 中提取帧...不幸的是我刚刚找到了如何获取它们的持续时间...

我真的需要提取 GIF 帧及其持续时间,以便在每个帧上应用一些调整大小、旋转等,然后用编辑过的帧重新生成 GIF!

我不想使用任何软件、外部库(如 ImageMagick),只是 PHP:实际上我需要让我的类http://phpimageworkshop.com/使用动画 GIF。

如果你有任何想法,我在听你的^^!

4

4 回答 4

25

我花了一天的时间创建一个基于这个类的类,以仅使用 PHP 来实现我想要的!

你可以在这里找到它:https ://github.com/Sybio/GifFrameExtractor

感谢您的回答!

于 2012-09-23T17:53:12.777 回答
5

好吧,我真的不建议这样做,但这里有一个选项。动画 gif 实际上只是由分隔符“\x00\x21\xF9\x04”连接在一起的多个 gif。知道了这一点,您只需将图像作为字符串拉入 PHP,运行分解,然后循环遍历运行转换的数组。代码可能看起来像这样。

$image_string = file_get_contents($image_path);

$images = explode("\x00\x21\xF9\x04", $image_string);

foreach( $images as $image ) {
  // apply transformation
}

$new_gif = implode("\x00\x21\xF9\x04", $images);

我不是 100% 确定重新连接图像的细节,但这里是关于动画 GIF 文件格式的维基百科页面

于 2012-09-23T14:34:04.147 回答
2

我是https://github.com/stil/gif-endec库的作者,该库在解码 GIF 时比Sybio/GifFrameExtractor接受答案的库要快得多(大约 2.5 倍)。它的内存使用量也更少,因为它允许您在解码时一帧接一帧地处理,而无需一次将所有内容加载到内存中。

小代码示例:

<?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) {
    /**
     * Write frame images to directory
     */
    $event->decodedFrame->getStream()->copyContentsToFile(
        __DIR__ . "/frames/frame{$event->frameIndex}.gif"
    );
});
于 2015-02-03T20:59:11.423 回答
1

我不想使用任何软件、外部库(如 ImageMagick)

好吧,祝你好运,因为 Zend 引擎导出到 PHP 运行时的功能中有 90% 来自库。

如果你有任何想法,我在听你的^^!

解析GIF格式的二进制数据。除其他外,您可以使用 unpack()。

于 2012-09-23T13:39:30.777 回答