28

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.

  • 1
    How about dividing the *.png files into manageable chunks? Let's say all filenames start with a digit, then convert -delay 2 -loop 0 0*.png animated.gif will convert only the files that start with a '0'. And so on. – Jos Jan 14 '15 at 13:44
  • 2
    So each .png is in the order of 1 Mb? In that case, all I can think of is to first convert the .png files to a lower resolution or color depth, to make them smaller. – Jos Jan 14 '15 at 13:51
  • 10
    You say that you could use another open format. It seems to me that gif isn't exactly the best format for thousands of frames. Have you considered encoding a video with Ogg Theora instead? – rekado Jan 14 '15 at 15:11
  • 1
    Perhaps take a look at gifsicle, if you really want to use GIF? (Although, as others have said, this isn't what GIF was made for; OGG would be a better choice.) – wchargin Jan 14 '15 at 23:32
  • 1
    Re. "where all the memory is going": 65 Kb is the file size of a compressed image. When uncompressed, the image takes roughly 4 x width x height bytes, so a 1024x768 image would take ~3Mb of RAM. Multiply that by "a few thousand" and you'll see where the memory is going... – Sergey Jan 20 '15 at 20:49
32

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:

10

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
7

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
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.

  • I'd like to also point out that APNG is non-standard and despite having been around for 7 years is still very obscure. – Pharap Jan 15 '15 at 7:28
  • For a scientific demonstration, where you might be able to choose the browser used for it, this might still be a simple and robust solution. – MvG Jan 15 '15 at 17:17
  • It depends who has to view the demonstration. It wouldn't be very good to hand copies out to the viewers and then two thirds have to go off and download Firefox just to view it. Not the kind of impression I'd like to make if I were making an important scientific demonstration. If it's only intended to be viewed as part of the demonstration then fair enough, but it may not be suitable for other situations. – Pharap Jan 16 '15 at 0:10
3

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
  • This approach has the added benefit that you could later mux in voice-over or music audio which is impossible with the Graphics Interchange Format. – Elder Geek Jul 5 '16 at 19:57
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.

  • Let me put it this way: gifsicle already has a smaller footprint than ImageMagick - if you find that it still uses too much memory for the task at hand, then you can use --conserve-memory – codehead Jan 16 '15 at 10:11
  • Ohh, I think I misread what you were saying, that the switch would use more memory, which doesn't make much sense. never mind. – curiousdannii Jan 16 '15 at 11:30
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.

  • Thank you Sergey. In fact this is not for display on a webpage. +1 for the idea, though. – dotancohen Jan 20 '15 at 21:02

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.