Convert thousands of .pngs to animated .gif, `convert` uses too much memory

Solution 1:

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:

  • Create a video slideshow from images
  • FFmpeg and H.264 Encoding Guide

Solution 2:

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

Solution 3:

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