Converting Animated GIFs to AnimationDrawables

A few days ago, Marc Poppleton tweeted:

Instead of using an AnimationDrawable or the Animation framework, embed a WebView displaying an animated GIF.

Wanting an animated GIF is understandable, in that animated GIFs are easy for designers to create. However, using a WebView for the sole purpose of displaying an animated GIF is, to use an American expression, “like swatting a fly with a Buick”.

So, I tossed together a quick Ruby script to convert animated GIFs to AnimationDrawables at the command line.

If you are familiar with Ruby environments, using this script should be a matter of downloading it and installing the three gems that it depends upon (RMagick, Slop, and Builder). RMagick is a bit of a pain to install, due to its dependence upon ImageMagick, but there are recipes for getting that going on most major OS versions. It is set up to be marked as executable via chmod and run directly on Linux; on other operating systems, you would run the script via the ruby interpreter.

There are four command-line switches:

  • -i provides a path to the animated GIF to be converted. The name of this GIF will be used as the basis for your resource names, so name the GIF how you want the output to be named.

  • -o provides a path to a directory (that will be created if it does not already exist) where output files will be written, representing the generated AnimationDrawable.

  • -d should be a standard Android density indicator (e.g., mdpi, hdpi), indicating what density directory should be used for dumping the GIF frames into as PNG files.

  • Optionally, --oneshot adds the android:oneshot="true" attribute to the AnimationDrawable, indicating that instead of infinitely looping, it should only run through the animation once.

So, if you were to run:

ruby gif2animdraw -i something.gif -o res -d mdpi

you would get res/drawable/something.xml with the AnimationDrawable itself, plus res/drawable-mdpi/something_*.png files, one per frame in the animation. The AnimationDrawable XML will contain android:duration values for the frames based upon the input GIF.

I have only tested this on a couple of GIFs, and so this script may have some bugs. Comment on the gist if you run into problems with the script.

Eventually — if nobody beats me to it, which would be really cool — I’ll slap a Web front end on this functionality, so you upload the GIF and download a ZIP with the animation.