将成千上万的.png转换为动画的.gif,`convert`占用过多内存


29

许多询问 如何 从一组png图像中创建动画gif问题建议使用ImageMagick 命令的变体: convert

convert -delay 2 -loop 0 *.png animated.gif

但是,我有几千张图像,因此convert用尽了所有内存,交换,然后崩溃了。存在哪些替代软件,它们更注重内存?如果.gif不支持,我可以使用其他开放格式,并且我确实更喜欢CLI工具。


1
如何将* .png文件划分为可管理的块?假设所有文件名均以数字开头,然后convert -delay 2 -loop 0 0*.png animated.gif仅转换以“ 0”开头的文件。等等。
2015年

2
那么每个.png大小约为1 Mb?在这种情况下,我能想到的就是首先将.png文件转换为较低的分辨率或颜色深度,以使其更小。
2015年

10
您说可以使用另一种开放格式。在我看来,gif并不是成千上万帧的最佳格式。您是否考虑过用Ogg Theora编码视频?
rekado 2015年

1
如果您真的想使用GIF,也许看看gifsicle?(尽管,正如其他人所说的,这不是GIF的目的; OGG是更好的选择。)
wchargin 2015年

1
回覆。“所有内存都将流向何处”:65 Kb是压缩图像的文件大小。如果未压缩,则映像大约需要4 x宽x高字节,因此1024x768映像大约需要3Mb的RAM。将其乘以“几千”,您将看到内存的去向……
谢尔盖2015年

Answers:


33

听起来您正在尝试制作视频。如果是这样,那么我会使用适当的视频格式。

在这种情况下,我将使用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:将帧速率设置为一半FPS,即每帧2秒。
  • -i img%04d.png:告诉FFmpeg读取这些文件img0000.png虽然img9999.png
  • -c:v libx264:使用视频编解码器libx264。
    • 如果愿意,您可以在此处指定视频压缩参数:
    • -crf <number>:质量设置。0到51。默认值为23。0是真正的无损编码,这将是相当高的带宽。18在视觉上几乎无损。
  • -r 30:将输出帧频设置为30 FPS。每个输入图像将被复制,以使输出达到您在此处指定的效果。您可以将此参数保留为关闭状态,并且输出文件将采用输入帧速率,但是当我刚才尝试生成的电影时,该电影无法正确显示。
  • out.mp4:输出文件名。

参考文献:


1
从前一天开始,Frantique答案的扩展很好。
年长者极客

下面是一个简单的ffmpeg VS ImageMagick的基准混凝土试验数据:askubuntu.com/questions/648244/...
西罗桑蒂利新疆改造中心法轮功六四事件

11

就个人而言,我只会在有限数量的文件上启动它,而不是一次启动。例如,如下所示:

#!/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

8

使用-limit memory 1GiB限制的内存量convert使用。

数千张图像将创建一个巨大的GIF,大多数计算机将难以显示该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

1
谢谢您,该解决方案效果很好。可能还需要增加/etc/ImageMagick-6/policy.xml中允许的内存限制,请参阅github.com/ImageMagick/ImageMagick/issues/…了解更多信息
Louis Gagnon

4

如果.gif不支持,我可以使用其他开放格式

也许APNG对您有用。某些浏览器(包括Firefox)支持该功能,但目前不包括Chrome和IE。由于它只是PNG扩展名,因此将PNG转换为APNG 非常简单。该apngasm工具可以做到这一点。但是格式是如此简单,以至于我最近为Sage编写了一个APNG汇编程序。修改该代码将是替代方法。


我还要指出,APNG是非标准的,尽管已经存在了7年之久,但它仍然非常晦涩。
法拉普

对于科学演示,您可能可以选择用于该演示的浏览器,但这仍然是一个简单而强大的解决方案。
MvG

这取决于谁必须查看演示。将副本分发给查看者并不是很好,然后只有三分之二的人不得不下载Firefox才能查看它。如果要进行重要的科学演示,那不是我想要的印象。如果仅打算将其视为演示的一部分,那么就足够公平了,但可能不适用于其他情况。
法拉普2015年

3

如果您有数千个png-s,则anigif格式很奇怪。我将以这种方式使用avconv

 avconv -i "%d.png" -r 25 -c:v libx264 -crf 20 -pix_fmt yuv420p animated.mov

这种方法还有一个好处,就是您以后可以混入画外音或音乐音频,而这在图形交换格式中是不可能的。
极客长老

2

gifsicle是用于处理GIF动画的命令行实用程序。如果您愿意以内存换取速度,则可以使用其--conserve-memory开关。


让我这样说:gifsicle已经比ImageMagick占用空间小-如果您发现它仍然为当前的任务使用过多的内存,可以使用--conserve-memory
代码头

哦,我想我误会了您的意思,即交换机将使用更多的内存,这没有多大意义。没关系。
curiousdannii 2015年

2

除了其他答案:由于您要生成GIF文件,因此我假设您要在网页上显示图像。如果是这样,我根本不会理会您的PNG转换。只需在Google上搜索“ javascript幻灯片”,即可使用数百万个免费脚本之一。或自己写,这确实很简单。

这样做的好处是:

  • 随时仅在浏览器中加载一张图像,幻灯片播放开始很快,并且不会占用用户计算机上的大量RAM。

  • 该解决方案可扩展到数百万张图像。或数十亿,如果您有足够的耐心观看所有节目:)

  • 您可以在页面上添加控件以暂停,快退,更改延迟或转到特定的帧。


谢谢你谢尔盖。实际上,这不是显示在网页上。+1,但是。
dotancohen
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.