如何使用PHP提取动态GIF的帧

10

我搜索了很久如何使用PHP从动态GIF中提取帧...

不幸的是,我只找到了如何获取它们的持续时间...

我真的需要提取GIF帧及其持续时间以对每个帧进行调整大小、旋转等操作,然后重新生成编辑过的GIF!

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

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


根据您的限制,我无法进行翻译。 - user557846
3
你可以看到,我找到了一个只使用PHP调整每个帧大小的类:https://gist.github.com/3769812。所以这是可能的,但该类的文档不太完善。如果没有更简单的解决方案,我会检查并理解其中的所有代码行:s - Sybio
4个回答

26

5

嗯,我不太建议这样做,但这是一个选项。动画gif实际上只是由分隔符"\x00\x21\xF9\x04"连接在一起的一系列gif图像。因此,您只需将图像作为字符串导入PHP,运行explode,并循环遍历数组运行转换即可。代码可能如下所示。

$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);

我不完全确定重新连接图像的具体方法,但是这里有关于动画GIF文件格式的维基百科页面(点击跳转)


我尝试了你的解决方案,但它不起作用 :( 无论如何还是谢谢 ^^ - Sybio
似乎对于OP提出的问题而言情况比这更加复杂(还涉及到头部和其他内容)。但我来这里是为了寻找一种在GIF文件中计算有多少帧的方法,二进制分隔符真是救命稻草!我刚刚使用了substr_count($image_string, "\x00\x21\xF9\x04"),这比使用类似Imagick这样的工具将整个图像读入内存更快,内存占用也更小。谢谢! - Seb

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

1
我不想使用任何软件或外部库(如ImageMagick)。
好吧,祝你好运,因为Zend引擎向PHP运行时导出的90%功能来自库。
如果你有任何想法,我在听着你^^!
解析GIF格式的二进制数据。您可以使用unpack()等方法。

你会如何使用unpack来分解动态gif的帧? - Chris Henry
我的答案提到了“除其他事项外”,如常规编程结构、循环、条件等。不是“unpack()”是关键词,而是解析 - Flavius
1
同意解析是关键。从我查看它支持的格式来看,unpack() 似乎不是获取动画 GIF 帧的可行方法。http://php.net/manual/en/function.pack.php - Chris Henry

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接