问题描述
许多 questions asking how to create an animated gif from a set of png images 建议使用 ImageMagick 的 convert
命令的变体:
convert -delay 2 -loop 0 *.png animated.gif
但是,我有几千张图像,因此 convert
用完了我所有的内存,交换,然后崩溃。有什么替代软件存在,哪个更 memory-conscious?如果不支持 .gif
,我可以使用另一种开放格式,而且我更喜欢 CLI 工具。
最佳方案
听起来您正在尝试制作视频。如果是这种情况,那么我会使用适当的视频格式。
在这种情况下,我将使用 ffmpeg 将单个 PNG 文件转换为 H.264 视频。由于 ffmpeg 用于处理可能长达数小时的视频,因此您的数千张图像应该没有问题。使用 H.264 而不是 gif 动画将大大提高图像质量。
像这样的事情应该适合你:
ffmpeg -framerate 1/2 -i img%04d.png -c:v libx264 -r 30 out.mp4
-
-framerate 1/2
:这将帧速率设置为 one-half FPS,或每帧 2 秒。 -
-i img%04d.png
:这告诉 ffmpeg 通过img9999.png
读取文件img0000.png
。 -
-c:v libx264
:使用视频编解码器 libx264。-
如果您愿意,可以在此处指定视频压缩参数:
-
-crf <number>
:质量设置。 0 到 51。23 是默认值。 0 是真正的无损编码,这将是相当高的带宽。 18 在视觉上几乎无损。
-
-
-r 30
:将输出帧率设置为 30 FPS。每个输入图像都将被复制,以生成您在此处指定的输出。您可以关闭此参数,输出文件将处于输入帧率,但我刚刚尝试时生成的电影无法正常显示。 -
out.mp4
:输出文件名。
参考:
次佳方案
就个人而言,我只会在有限数量的文件上启动它,而不是一次启动。例如,这样的事情:
#!/usr/bin/env bash
## Collect all png files in the files array
files=( *png )
## How many should be done at once
batch=50
## Read the array in batches of $batch
for (( i=0; $i<${#files[@]}; i+=$batch ))
do
## Convert this batch
convert -delay 2 -loop 0 "${files[@]:$i:$batch}" animated.$i.gif
done
## Now, merge them into a single file
convert animated.*.gif all.gif
第三种方案
使用 -limit memory 1GiB
来限制 convert
使用的内存量。
数以千计的图像将创建一个巨大的 GIF,大多数计算机将难以显示。如果可能,我将我的动画 GIF 保持在 200 张以下。越少越好。如果您给图像编号,此命令将删除奇数编号的图像 rm *[13579].png
。
所以这是我从电影场景创建动画 GIF 的典型工作流程:
avconv -ss 00:26:00 -i someMovie.mpg %5d.png
rm *[13579].png
convert -limit memory 1GiB -loop 0 -layers optimize -resize 400 *.png output.gif
第四种方案
如果你有数千个 png-s,anigif 格式就很奇怪了。我会这样做,使用 avconv
:
avconv -i "%d.png" -r 25 -c:v libx264 -crf 20 -pix_fmt yuv420p animated.mov
第五种方案
I could use another open format if
.gif
is not supported
或许 APNG 对你有用。它由 some browsers 支持,包括 Firefox,但目前不包括 Chrome 和 IE。由于它只是一个PNG扩展,因此将PNG转换为APNG非常简单。 apngasm 工具可以做到这一点。但是格式非常简单,以至于我最近自己为 Sage 编写了一个 APNG 汇编程序。调整 that code 将是另一种选择。