ImageMagick animated GIF commands
Build an animated GIF from frames, resize one without breaking the animation, shrink an oversized GIF, and split a GIF into frames. Explains why -coalesce is mandatory.
Build a GIF from frames
magick -delay 8 -loop 0 frame_*.png +dither -colors 128 \
-layers Optimize output.gif
-delay and -loop must appear before the input frames — they are settings applied to images read afterwards. Put them at the end and they do nothing.
-delay 8— the unit is hundredths of a second, so 8 is roughly 12.5 fps. Browsers clamp anything below 2 to about 10 fps, so going lower is pointless.-loop 0— loop forever. Any other number loops that many times.
Zero-pad your frame numbers. Shell globs sort as text, so frame_10.png comes before frame_2.png and your animation plays out of order. Name them frame_0002.png.
Resize an animated GIF
magick input.gif -coalesce -resize 320x -layers Optimize output.gif
-coalesce is not optional. An optimised GIF does not store complete frames — most frames are just the rectangle that changed since the previous one. Resizing those fragments directly scales the fragments, and the animation turns into visual garbage. -coalesce rebuilds every frame as a full image first; the trailing -layers Optimize puts the size saving back afterwards.
Shrink an oversized GIF
magick input.gif +dither -colors 64 -layers Optimize output.gif
Two levers do most of the work:
- Colour count. 256 → 128 → 64 shrinks the palette geometrically. Screen recordings of flat UI survive 64 colours easily; photographic content does not.
-layers Optimize. Stores only the changed rectangle of each frame. On a recording with a static background this alone often halves the file.
+dither turns dithering off. Keep it off for UI recordings and screencasts; turn it on for photographic content where banding would otherwise show.
Dropping frames
If it is still too large, remove every second frame and double the delay:
magick input.gif -coalesce -delete '1--1/2' -set delay 16 \
-layers Optimize output.gif
Split a GIF into frames
magick input.gif -coalesce frame_%03d.png
Without -coalesce you get the stored difference frames rather than what the animation actually looks like.
Inspect a GIF
magick identify -format '%n frames, %wx%h\n' input.gif
If your source is a video
ImageMagick is the wrong tool. It shells out to ffmpeg anyway and does a poor job of palette selection. Use ffmpeg's two-pass palette filters directly:
ffmpeg -i input.mp4 -vf "fps=12,scale=480:-1:flags=lanczos,palettegen" palette.png
ffmpeg -i input.mp4 -i palette.png -lavfi "fps=12,scale=480:-1:flags=lanczos,paletteuse" output.gif