nullprogram.com/blog/2012/04/10/
This tutorial is very similar to my video editing tutorial.
That’s because the process is the same up until the encoding stage,
where I encode to GIF rather than WebM.
So you want to make your own animated GIFs from a video clip? Well,
it’s a pretty easy process that can be done almost entirely from the
command line. I’m going to show you how to turn the clip into a GIF
and add an image macro overlay. Like this,
The key tool here is going to be Gifsicle, a very excellent
command-line tool for creating and manipulating GIF images. So, the
full list of tools is,
Here’s the source video for the tutorial. It’s an awkward video my
wife took of our confused cats, Calvin and Rocc.
My goal is to cut after Calvin looks at the camera, before he looks
away. From roughly 3 seconds to 23 seconds. I’ll have mplayer give me
the frames as JPEG images.
mplayer -vo jpeg -ss 3 -endpos 23 -benchmark calvin-dummy.webm
This tells mplayer to output JPEG frames between 3 and 23 seconds,
doing it as fast as it can (-benchmark
). This output almost 800
images. Next I look through the frames and delete the extra images at
the beginning and end that I don’t want to keep. I’m also going to
throw away the even numbered frames, since GIFs can’t have such a high
framerate in practice.
There’s also dead space around the cats in the image that I want to
crop. Looking at one of the frames in GIMP, I’ve determined this is a
450 by 340 box, with the top-left corner at (136, 70). We’ll need
this information for ImageMagick.
Gifsicle only knows how to work with GIFs, so we need to batch convert
these frames with ImageMagick’s convert
. This is where we need the
crop dimensions from above, which is given in ImageMagick’s notation.
ls *.jpg | xargs -I{} -P4 \
convert {} -crop 450x340+136+70 +repage -resize 300 {}.gif
This will do four images at a time in parallel. The +repage
is
necessary because ImageMagick keeps track of the original image
“canvas”, and it will simply drop the section of the image we don’t
want rather than completely crop it away. The repage forces it to
resize the canvas as well. I’m also scaling it down slightly to save
on the final file size.
We have our GIF frames, so we’re almost there! Next, we ask Gifsicle
to compile an animated GIF.
gifsicle --loop --delay 5 --dither --colors 32 -O2 *.gif > ../out.gif
I’ve found that using 32 colors and dithering the image gives very
nice results at a reasonable file size. Dithering adds noise to the
image to remove the banding that occurs with small color palettes.
I’ve also instructed it to optimize the GIF as fully as it can
(-O2
). If you’re just experimenting and want Gifsicle to go faster,
turning off dithering goes a long way, followed by disabling
optimization.
The delay of 5 gives us the 15-ish frames-per-second we want — since
we cut half the frames from a 30 frames-per-second source video. We
also want to loop indefinitely.
The result is this 6.7 MB GIF. A little large, but good enough. It’s
basically what I was going for. Next we add some macro text.
In GIMP, make a new image with the same dimensions of the GIF frames,
with a transparent background.
Add your macro text in white, in the Impact Condensed font.
Right click the text layer and select “Alpha to Selection,” then under
Select, grow the selection by a few pixels — 3 in this case.
Select the background layer and fill the selection with black, giving
a black border to the text.
Save this image as text.png, for our text overlay.
Time to go back and redo the frames, overlaying the text this
time. This is called compositing and ImageMagick can do it without
breaking a sweat. To composite two images is simple.
convert base.png top.png -composite out.png
List the image to go on top, then use the -composite
flag, and it’s
placed over top of the base image. In my case, I actually don’t want
the text to appear until Calvin, the orange cat, faces the camera.
This happens quite conveniently at just about frame 500, so I’m only
going to redo those frames.
ls 000005*.jpg | xargs -I{} -P4 \
convert {} -crop 450x340+136+70 +repage \
-resize 300 text.png -composite {}.gif
Run Gifsicle again and this 6.2 MB image is the result. The text
overlay compresses better, so it’s a tiny bit smaller.
Now it’s time to post it on reddit and
reap that tasty, tasty karma.
(Over 400,000 views!)