### Jamie Oaks

Evolutionary biologist.

# Converting PDF slides to animated GIFs and videos with ImageMagick

The power and flexibility of the ImageMagick suite of software never fails to amaze me. Not only does ImageMagick provide several command-line tools capable of meeting all your image editing/conversion needs, there are also APIs for over a dozen languages, including Python, Ruby, and Perl. I should preface this post by declaring that I am not an expert on the use of ImageMagick, but I have used it successfully to script solutions for many of my image-editing needs. One recent task for which it spared me from having to resort to using a GUI-based image editor was converting a series of PDF slides into an animation for one of my recent posts. I wanted to document how I did this for my own memory, and in case someone else might find it useful.

My first step was to use the convert tool to convert the slides into separate PNG files:

The -density option determines the resolution (in dots per inch) at which to rasterize the PDF. The -strip option removes any comments or profiles from the output images; I use this option a lot to reduce the file size of images for the web. The -resize option determines the size of the output PNG. This option is very flexible in the arguments it can handle; here I use the @ symbol to specify the area in pixels (ImageMagick will preserve the aspect ratio). To further reduce file size, I specified 8-bit PNG files using the PNG8: syntax. Lastly, the slide-%02d.png syntax in the output file name specifies that I want the slides to be named slide-00.png, slide-01.png, slide-02.png, etc.

Next, we can convert the PNGs into an animated GIF:

I have no idea how the -layers OptimizePlus option works, but it optimizes the final output to reduce the animated file size. The -delay option specifies the number of ticks (the default rate is 100 ticks per second) to pause each image. The options in the command above specify to spend 3/4 of a second on the first 15 slides, and then 3 seconds on the last three slides. The -loop option specifies the number of times the GIF animation should repeat; setting it to zero will cause the GIF to repeat indefinitely.

We can use the same command (minus the loop option) to create a movie out of the PNG images:

Here, we specified an MP4, but other output formats are supported. I think ImageMagick uses ffmpeg in the background to make the video, so you might have to install it. You can also use ffmpeg directly:

Either way, you should end up with a video like the following:

NOTE: The video is not displaying for some OS/browser combinations. If it’s not working for you, check out the animated GIF below.

Pretty slick; with just a few simple command lines, we went from a PDF to an animated GIF and movie. Ok, let’s clean up all those intermediate PNGs:

Next, we can make a faux play-button image, which, when used with a little javascript, will make the GIF appear controllable. To make the “play button,” we’ll start with a simple blue triangle, which you can download:

We can use convert to add a shadow to the triangle to make it stand out a bit:

This command was taken, almost verbatim, from the fantastic ImageMagick documentation.

Next, we will parse the GIF frames into individual PNG files in order to overlay the play button onto the first frame.

NOTE: I realize we could have avoided this step by simply using the PNG files we just deleted above, but I often have a GIF as the starting point for this task, and so I wanted to document how to convert the GIF into separate frames.

Next, let’s overlay the shadowed play button:

Now, slides.png is the first frame of the GIF and looks like it has a “play” button on it. Notice that I named the output “play-button” as slides.png such that the prefix matches the slides.gif file we made above. That was intentional, because now we can use some javascript sleight-of-hand to make the GIF appear controllable on the web. Here’s the javascript magic that I found on codepen:

Adding this javascript to our page allows us to use the gif-hover class when embedding the PNG/GIF as an image:

The result is the following GIF that will “play” when moused over.

If we prefer to “control” the GIF with mouse clicks, we can modify the javascript a bit:

Now, we can use the gif-click class for the image:

The result is the following GIF that will start/stop with mouse clicks.

Notice, the javascript functions work by simply changing the path from the “play-button” PNG file to the GIF, and vice versa. For this to work, the files need to be in the same directory and share the same prefix. A little hacky, no doubt, but it works.