123

Is there a tool to create a gif animation from a set of png files?

I tried the convert command from the ImageMagick suite, but this doesn't always succeed. Also, I have several issues with this:

  1. I can't tell what the progress is.
  2. No matter what I try, the -delay flag doesn't change the frame rate of the gif animation.
  3. convert determines the frame order based upon the alphabetical order of the files names. This means that name500.png will be placed right after name50.png and not after name450.png I can fix this by adding 0's but this is annoying.
4
  • [News] There is a massive overlap between Ubuntu Stackexchange and Unix Stackexchange. I tried to categorize some threads here.
    – hhh
    Commented Dec 30, 2012 at 1:07
  • Regarding item 3., you can still use convert after sorting the files. Probably, something like this works files=$(ls name*png | sort -n -tname -k1); convert $files animation.gif
    – altroware
    Commented Jun 11, 2017 at 16:26
  • For Point 1: convert has a -monitor parameter that tracks the process
    – Curlew
    Commented Dec 3, 2018 at 22:02
  • @hhc - all the categorization is just a link to an answer with 5 links; only one of them seems related, but is just a link to the above question. - A comment by @Luke gives a simple solution: convert -delay 200 -loop 0 *.jpg output.gif.
    – cipricus
    Commented Oct 26, 2019 at 22:11

9 Answers 9

121

ImageMagick's convert is a handy command line tool to do that. cd to the folder containing your png-files and run this command:

convert -delay 10 -loop 0 *.png animation.gif

Source: http://ubuntuforums.org/showthread.php?t=1132058

7
  • 15
    The question mentions convert and some problems using it. Your answer doesn't address any of them.
    – Mat
    Commented Nov 6, 2011 at 0:36
  • 4
    As of ImageMagick version 6.8.7-4 2013-11-02 Q16 this worked for me. Commented Nov 6, 2013 at 17:11
  • 10
    This works, but 10 means 10 * 10ms, so pretty fast. A delay of a 100 is 1 second. Commented Sep 27, 2015 at 8:01
  • 11
    use option -dispose previous or -dispose 2 if you are working with transparent PNGs Commented Aug 31, 2016 at 1:00
  • 10
    note to myself: brace expansion can be helpful for specifying the list of images as arguments, for example pic_{0..20..2}.png expands to pic_0.png, pic_2.png all the way to pic_20.png
    – Yibo Yang
    Commented Sep 6, 2017 at 2:51
63

Newer versions of ffmpeg have no -sameq (see faq) but do have GIF support.

ffmpeg -i %03d.png output.gif

Where %03d is the frame ID in 3 digits.

You may also try to use ffmpeg to create a movie out of a sequence of images and then convert the movie to a GIF animation (again using ffmpeg).

# cf. http://pages.uoregon.edu/noeckel/MakeMovie.html

# first convert an image sequence to a movie
ffmpeg -sameq -i %03d.jpg output.mp4

# ... and then convert the movie to a GIF animation
ffmpeg -i output.mp4 -pix_fmt rgb24 -s qcif -loop_output 0 output.gif
4
  • 14
    This instruction is out of date.
    – pronebird
    Commented Jul 16, 2014 at 19:03
  • 3
    The sameq option is not available anymore. Further, for me, this overwrites the original image files and does not produce a valid movie file.
    – Lode
    Commented Nov 8, 2014 at 18:57
  • What's the point of leaving the -sameq code there? Why would you even want to use a lossy video format (output.mp4) as a temporary? And if so, why "same quality" as the input, instead of very high bitrate? Artifacting from that is just going to make things worse for the GIF encoder. If you did need to use a video as a temporary, you'd want to use something lossless like huffyuv. Or MJPEG with no transcoding, just remux the input jpegs into an MJPEG. (-codec:video copy). Commented Dec 7, 2016 at 15:25
  • The -loop_output argument does not exist. Commented Jul 3, 2020 at 8:55
24

The convert's --delay option only applies to the next image on the command line. So convert -delay 10 * will only set the delay of the first frame to 0.1 second. The option need to be repeated:

convert $(for a in *; do printf -- "-delay 10 %s " $a; done; ) result.gif

For your sorting need, convert does not sort frames, the shell globing * does. If you know your frames are numbered from 0 to 700, you can just compute the numbers yourself:

convert $(for ((a=0; a<700; a++)); do printf -- "-delay 10 name%s.png " $a; done;) result.gif
2
  • 8
    I do not experience this behavior with convert, for me convert -delay 1000 -loop 0 *.png animation.gif does add a 10s delay between each image.
    – Lode
    Commented Nov 8, 2014 at 18:52
  • 1
    You can also use version sort of the ls command. That is: convert -delay 1000 $(ls -v name*png) output.gif
    – erik
    Commented Apr 5, 2015 at 20:37
21

ffmeg important GIF options + test data

To complement this answer:

wget -O opengl-rotating-triangle.zip https://github.com/cirosantilli/media/blob/master/opengl-rotating-triangle.zip?raw=true
unzip opengl-rotating-triangle.zip
cd opengl-rotating-triangle
ffmpeg \
  -framerate 60 \
  -pattern_type glob \
  -i 'tmp.*.png' \
  -r 15 \
  -vf scale=512:-1 \
  out.gif \
;

The test data was generated with: https://stackoverflow.com/questions/3191978/how-to-use-glut-opengl-to-render-to-a-file/14324292#14324292

The important ffmpeg options I wanted to highlight are:

  • -pattern_type glob: convenient way to select images
  • -framerate 60 and -r 15: assume 60 FPS on input images (ffmpeg cannot know otherwise since no FPS data in images as in video formats), pick one every 4 images so reduce size (4 == 60 / 15)
  • -vf scale=512:-1: set the width, scale height proportionally, usually to reduce size and save space

See also:

Tested in Ubuntu 18.10, ffmpeg 4.0.2.

1
  • 1
    Thanks a lot, this was highly useful to me. Commented Jul 3, 2020 at 8:54
8

Update:

Use convert for the png-to-gif, then use gifsicle for the animation. It's not a One App To Do It All solution, but scriptable, for sure.


GIMP can create animated gifs and provides control for timing/delay and repeat, etc

2
  • 4
    I know about the gimp but I don't know how to script it. Besides, the using the gimp to create animation is like killing a fly with a cannon
    – Yotam
    Commented Nov 7, 2011 at 7:58
  • 1
    That's a bad idea; the quality will be horrible, as each frame will be quantized separately.
    – Clément
    Commented Jul 5, 2016 at 13:27
3

ImageMagick can generate a good quality gif animation. Check this video - http://www.youtube.com/watch?v=OFusYizJ-bA

5
  • 8
    Welcome to Unix & Linux! Generally we like answers on the site to be able to stand on their own - Links are great, but if that link ever breaks the answer should have enough information to still be helpful. Please consider editing your answer to include more detail. See the FAQ for more info.
    – slm
    Commented Apr 18, 2013 at 20:20
  • What a useful comment above....
    – Luke
    Commented Jul 10, 2018 at 6:42
  • 3
    convert -delay 200 -loop 0 *.jpg output.gif
    – Luke
    Commented Jul 10, 2018 at 6:42
  • @Luke - out of all the chaos posted under this question your comment was most useful
    – cipricus
    Commented Oct 26, 2019 at 22:07
  • For me too, the solution by Luke made my day.
    – doctorate
    Commented Jul 21, 2023 at 9:22
2

ffmpeg can do it all for you but it is really hard to get your head around it. I wrote a tiny script to do the job so I don't have to remember. It runs through the images twice: pass "a" to work out an optimal colour palette, then pass "b" to actually create the gif file using the created palette. Paste the following into a text file:

#!/bin/bash
ffmpeg -framerate 24 -start_number_range 999 -f image2 -i $1%3d.png -filter_complex "[0:v] split [a][b];[a] palettegen [p];[b][p] paletteuse" $1.gif

Save the file as "creategif", or something else to your taste, make it executable and put it in the same directory as your sequence of pngs

For a sequence foobar004.png, foobar005.png, foobar006.png...

open a command line and cd to the directory with everything in it then type

./creategif foobar

and it will create a file foobar.gif from the png's. You could add a few parameters to the script to make it a bit more flexible, but I find it easier to just hack the script if I want a different framerate or something. Many thanks to whoever it was on this forum that steered me in the right direction a few years back.

1

In order to get the frames in numeric order (i.e. 1.png, 2.png) rather than alphabetical, do this:

files=$(ls | sort --version-sort); convert -delay 10 loop 0 $files animation.gif
-3

In regards to point 2

The version of ImageMagick "display" I have (ImageMagick 6.7.2-7 2017-01-12) ignores the frame rate set using the convert command to produce the animated gif. Try another program to view the animate gif like firefox.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .