38

Many of the questions asking how to create an animated gif from a set of png images suggest to use a variant of ImageMagick's convert command:

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

However, I have a few thousand images and thus convert uses up all my memory, swap, and then crashes. What alternative software exists, which is more memory-conscious? I could use another open format if .gif is not supported, and I do prefer a CLI tool.

Zanna
  • 72,312
dotancohen
  • 2,864

8 Answers8

36

It sounds like you're trying to make a video. If that's the case, then I'd use a proper video format.

In this case, I'd use ffmpeg to convert the individual PNG files to a H.264 video. Since ffmpeg is made to work with videos that can be hours long, it should have no problem with your thousands of images. Using H.264 instead of animated gif will result in a vast improvement in image quality.

Something like this should work for you:

 ffmpeg -framerate 1/2 -i img%04d.png -c:v libx264 -r 30 out.mp4
  • -framerate 1/2: This sets the framerate to one-half FPS, or 2 seconds per frame.
  • -i img%04d.png: This tells ffmpeg to read the files img0000.png though img9999.png.
  • -c:v libx264: Use video codec libx264.
    • You can specify video compression parameters here, if you like:
    • -crf <number>: Quality setting. 0 to 51. 23 is the default. 0 is true lossless encoding, which will be quite high bandwidth. 18 is nearly visually lossless.
  • -r 30: Set the output framerate to 30 FPS. Each of the input images will be duplicated to make the output what you specify here. You can leave this parameter off, and the output file will be at the input framerate, but the resulting movie didn't display properly when I tried it just now.
  • out.mp4: Output filename.

References:

David Yaw
  • 461
  • 3
  • 4
15

Personally, I would just launch it on limited numbers of files instead of all at once. For example, something like this:

#!/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
terdon
  • 104,119
10

Use -limit memory 1GiB to limit the amount of memory convert uses.

1000s of images would create a huge GIF that most computers will struggle to display. I keep my animated GIFs below 200 images when possible. The fewer the better. If you number your images, this command will delete the odd numbered images rm *[13579].png.

So here is my typical workflow for creating an animated GIF from a movie scene:

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
PLA
  • 3,162
4

If you have thousands of png-s, the anigif format is weird. I would do it in this way, using avconv:

 avconv -i "%d.png" -r 25 -c:v libx264 -crf 20 -pix_fmt yuv420p animated.mov
Frantique
  • 8,673
4

I could use another open format if .gif is not supported

Perhaps APNG is of use to you. It's supported by some browsers, including Firefox but at the moment excluding Chrome and IE. Since it's just a PNG extension, it's very simple to convert PNGs to APNG. The apngasm tool can do that. But the format is so simple that I recently wrote an APNG assembler myself for Sage. Adapting that code would be an alternative.

MvG
  • 1,536
2

gifsicle is a command-line utility to handle GIF animations. If you are willing to trade memory for speed, you can use its --conserve-memory switch.

codehead
  • 121
2

In addition to other answers: since you want to produce a GIF file, I assume you want to display the image on a web page. If so, I would not bother converting your PNGs at all. Just google for "javascript slideshow" and use one of the millions of free scripts. Or write your own, this is really trivial.

The benefits of doing it this way are:

  • only one image is loaded in the browser at any time, the slideshow starts fast and does not consume much RAM on the user's machine.

  • the solution scales to millions of images. Or billions, if you're patient enough to watch them all :)

  • You can add controls to your page to pause, rewind, change the delay or go to a particular frame.

Sergey
  • 44,353
0

You can use apng2gif to achieve the same. From the man page:

Progrmam apng2gif converts APNG into animated GIF format.

The Animated Portable Network Graphics (APNG) file format is an extension to the Portable Network Graphics (PNG) specification. It allows for animated PNG files that work similarly to animated GIF files, while retaining backward compatibility with non-animated PNG files and adding support for 8-bit transparency and 24-bit images.

Default run values are /t 128, no background color. A short syntax hlp is provided without any command line arguments.

Run the following command to install the package:

sudo apt install apng2gif

Then run the following command to convert all .png files to .gif:

find -type f -name "*.png" -exec apng2gif {} \;
Error404
  • 8,278
  • 3
  • 35
  • 60