从一组JPEG图像中创建动画GIF

64

我需要一个可以在Windows 7上进行脚本化的工具。这个图像将用于横幅中。


1
需要使用JPEG格式吗?JPEG转动画GIF可能会产生不必要的闪烁伪影,并且压缩比更差。为了获得最佳质量结果,您应该使用无损GIF或GIF到GIF格式。 - tenfour
1
@tenfour - 尽管你指出的是完全有效的,但这并不一定是经验法则。更重要的是,帧共享相似的颜色,因为如果它们没有共享调色板,最多只能使用 256 种颜色的 GIF 图像将会产生糟糕的结果,无论输入格式如何,并且通常会让人们想知道“为什么会变得粗糙?!” - Valentin Flachsel
3
使用带有3位数字的图像文件 IMG-001.jpgIMG-002.jpg 等等,每秒显示4张图像,您可以通过使用以下命令将结果生成为GIF格式:ffmpeg -f image2 -framerate 4 -i "IMG-%03d.jpg" Output.gif - caw
6个回答

135

Simon P Stevens的回答 差点就让我得到答案了:

ffmpeg -f image2 -i image%d.jpg video.avi
ffmpeg -i video.avi -pix_fmt rgb24 -loop_output 0 out.gif

让我们看看能否将其整理好。

经由avi的方式是不必要的。使用-pix_fmt选项中的rgb24是无效的,而-loop_output选项则会防止循环播放,这不是我想要的。我们有:

ffmpeg -f image2 -i image%d.jpg out.gif
我的输入图片标签是带有前导零的三位数字,并且我有30张这样的图片(image_001.jpg,image_002.jpg...),因此我需要修复格式说明符。
ffmpeg -f image2 -i image_%003d.jpg out.gif

我的输入图片来自手机相机,它们太大了!我需要将它们缩小。

ffmpeg -f image2 -i image_%003d.jpg -vf scale=531x299 out.gif

我还需要将它们顺时针旋转90度

ffmpeg -f image2 -i image_%003d.jpg -vf scale=531x299,transpose=1 out.gif

这个gif播放时帧与帧之间没有任何延迟,这很可能不是我们想要的效果。请指定输入图像的帧速率。

ffmpeg -f image2 -framerate 9 -i image_%003d.jpg -vf scale=531x299,transpose=1 out.gif
图像略微过大,因此我将裁剪100个像素的天空。转置使这有些棘手,我使用后旋转的x和y值:
ffmpeg -f image2 -framerate 9 -i image_%003d.jpg -vf scale=531x299,transpose=1,crop=299,431,0,100 out.gif

最终结果 - 我可以与世界分享我的伙伴惊人的面部表情:

使用ffmpeg创建的动画GIF示例


%003d 会被ffmpeg替换为路径 - image_C:/user/... - user25
1
很棒的答案!可惜它没有涉及到两步调色板优化:https://superuser.com/a/556031/142943 - juanitogan
7
如果您的图像索引不从零开始,请使用“-start_number xxx”选项。 - Raf
我的图像是合成的(即绘图),但出于某些我不知道的原因,当我使用 ffmpeg 时,生成的 gif 文件中会出现一些黄色线条;然而,当我改用 ImageMagick 的 convert 命令时,我没有遇到这个问题。 - today
1
image2代表什么? - wongz
1
image2 是 ffmpeg 解复用器(读取输入的部分)的名称。 image2 提供了在 -i 中使用的文件通配符,并知道如何将这些文件作为视频源读取。请参见 http://manpages.org/ffmpeg。 - dwurf

76
你可以使用ffmpeg来完成这个任务。
首先将图像转换为视频:
ffmpeg -f image2 -i image%d.jpg video.avi

(这将把当前目录中的图像文件(命名为 image1.jpg、image2.jpg 等)转换为名为 video.avi 的视频文件。)

然后将 avi 文件转换为 gif 文件:

ffmpeg -i video.avi -pix_fmt rgb24 -loop_output 0 out.gif

您可以在这里获取适用于Windows的FFmpeg二进制文件。


您也可以使用mplayer完成类似的操作。请参阅从多个输入图像文件进行编码

我认为命令行应该是这样的:

mplayer mf://*.jpg -mf w=800:h=600:type=jpg -vf scale=160:120 -vo gif89a:fps=3:output=out.gif

(其中800和600是源图像的宽度和高度,160和120是目标图像的宽度和高度。out.gif是你的目标文件名)


我刚刚测试了这两个方法,它们都可以正常工作。不过,使用mplayer获得的结果要好得多,因为我能够指定分辨率和帧速率。你的结果可能会有所不同,如果你仔细查找,我相信你还可以找到更多ffmpeg的选项。


2
这段代码与谷歌搜索排名良好,因此如果您想在数字前加零,请使用“%04d”(数字4将使用带有前缀0的4个数字位置)。 - user151496
1
未找到名为 image1d.jpg 的文件!尝试使用 cmd。 - user25
8
杰出的答案。只是让任何尝试使用它的人知道,将.avi转换为.gif的新标志是-loop,选项为0则表示无限循环。此外,我认为RGB配置文件标志(尽管我对颜色配置文件一无所知)使我的缩略图上出现了蓝色的点阵网格。 - Scott Anderson
2
转换为avi会降低质量,因为avi使用有损压缩技术,您认同吗? - Nagabhushan S N
1
@caw 我试过了。但是ffmpeg在gif中引入了一些伪像。视频上有一些点/斑点。你知道为什么吗? - Nagabhushan S N
显示剩余2条评论

58

使用 ImageMagick:

convert *.png a.gif

1
还可以在这里查看:https://dev59.com/51XTa4cB1Zd3GeqP48hv - psycho brm
1
我在使用.png文件时遇到了质量问题(由于透明度和分层),但通过改用.jpg文件解决了这些问题。 - gatlanticus
6
您可以使用-delay来设置每张图片显示的时间。请注意,该值以1/100秒为单位给出,即-delay 100表示每秒一帧的速率。 - luator
类似于 convert -delay 100 *.jpg Output.gif 这样的命令可以正常工作,但是似乎即使使用 -layers optimize,生成的文件大小也比 ffmpeg 大。 - caw

14

ffmpeg 转换至 .avi.avi 转换至 .gif 都可以使用,但需要注意的是您的图像必须按照完美递增的数字顺序命名,且不能有间隔。我编写了一个简单的 Python 脚本,将所有图像相应地重命名,以便此 ffmpeg 方法能够正常使用:

import os

files = [ f for f in os.listdir('.') if os.path.isfile(os.path.join('.',f)) and f.endswith('.jpg') ]
for i, file in enumerate(sorted(files)):
    os.rename(file, 'image%03d.jpg' % i)

后来我偶然发现一种比使用ffmpeg更简单的方法进行转换,就是使用ImageMagick的命令行转换工具,像这样:

convert image%03d.jpg[0-198] animated_gif.gif

这再简单不过了,朋友们。

代码片段在这里:https://gist.github.com/3289840


5
"图片必须按照完美递增的数字顺序命名" - 我猜你不知道 "-pattern_type glob",它允许使用任何名称的文件作为输入,例如,将当前目录中的所有 png 文件转换为 gif:ffmpeg -framerate 1/10 -pattern_type glob -i '*.png' output.gif - Lissanro Rayen
@LissanroRayen,如果-pattern_type可以与*.jpg源文件结合使用而不仅仅是*.png,那将非常棒。 - 1234ru

12

根据Simon P Stevens和dwurf的答案,我提出了这个简化的解决方案:

ffmpeg -f image2 -framerate 1 -i image%d.jpg video.gif

这导致每张图片的速率为1秒。根据您的需要调整帧率值。


12

我想在dwurf的回答中补充一点,这会生成一个具有标准256色调色板的gif,看起来不太美观。

我找到了两个博客帖子并根据我的需求进行了改编,以使用自定义调色板来提高动画的视觉质量:

生成颜色调色板:

ffmpeg -f image2 -i image%d.jpg -vf scale=900:-1:sws_dither=ed,palettegen palette.png
将图像转换为所需帧率的常规视频,因为第三个命令仅适用于单个输入视频而不是一堆图像。
ffmpeg -f image2 -framerate 1.2 -i image%d.jpg video.flv

现在将生成的视频和生成的调色板转换为更漂亮的gif:

ffmpeg -i video.flv -i palette.png -filter_complex "fps=1.2,scale=900:-1:flags=lanczos[x];[x][1:v]paletteuse" video.gif

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