Sunday, September 15, 2013

Creating animated GIFs and APNGs from videos

Linux Setup

For this project we will need two or three tools. We will need avconv to pull frames from a video file, and we will need gifsicle if we want to created animated GIFs and apngasm if we want to create animate PNGs. If you are on Debian, you can install libav-tools (which provides avconv) and gifsicle in the normal way, but see my previous post on how to install apngasm from source (you will also find an explanation of the differences between animated GIFs and PNGs, and when to use each). If you use another Linux distribution, check your package management system.

Windows Setup

To get this to work similarly on Windows, we will need some extra tools and the setup is a bit more complicated. To get glob expansion and redirection, we will install Cygwin. Cygwin provides a Linux-like environment on Windows, including the Bash shell and the GNU coreutils (basic commands like ls, cp, rm, mv, etc). The installer also serves as a package manager, allowing you to select the various software packages you want to install or upgrade. If you are not sure what you want, just install the default packages. This will provide a lot more than we need, but you will have a useful environment if you need it later. You can always run the installer again later if you want to install more packages.

You will need to install 7zip, since Libav binaries come in a .7z archive you will need 7zip to extract them. When using the most recent version of Libav (0.9.7) on Windows, all of the GIFs came out in grayscale, so I tried the same version that was included with Debian Wheezy (0.8.6) and found it to be working on Windows (YMMV).  Gifsicle and apngasm come in .zip archives. Gifsicle and apngasm both contain a single binary you can extract to wherever you would like. Libav is a bit more complicated, you will need to extract the bin, lib, and share directories. For simplicity, you could extract all of these directories to C:\, and then put the gifsicle.exe and apngasm.exe in C:\bin (or choose whatever directory structure seems suitable for you).

Now, it would be nice to put  the directory (or directories) containing our new tools in the system path variable, so Windows (and Cygwin) will know where to find them without us having to type the full path to the command. You can do that in cmd.exe like this:

setx path "%PATH%;C:\bin"

Now, for any of the following commands, we will use the Cygwin Terminal. If you are from a Windows background, you will notice that all of the paths are separated with forward slashes instead of back slashes (C:/Users/Name/Documents, rather than C:\Users\Name\Documents). If you have used Cygwin before, you will need to note that these are not Cygwin binaries we are using, so the path arguments they take will use Windows drive designations (C:/Users/Name/Documents, rather than /cygdrive/c/Users/Name/Documents). However, this only applied to arguments passed to the commands, if you are giving the full path to the command, you will be using the Cygwin form (/cygdrive/c/bin/avconv.exe).

Essentially, when you are running the following commands in Cygwin terminal on Windows, you will just add the drive letter (C:) in front of the file paths, and the commands will end with the .exe extension.

Extracting Images from the Video

The first step is to convert our video to a series of image files. Now when we do this, we need to know what frame rate we want our animation to run at, and how if we want to make it faster (or slower) than the original video. If we want it to run at the same speed, we will use the same frame rate when extracting the images as we will use when we create the animation. If we want to alter it's speed or playing time, we'll want to do a little math. For instance, suppose I want to make an animation of these roses blooming from youtube. The video runs for about a minute and a half, but let's say we want to see the whole process in about ten seconds in our animation. If we want our animation to run at 30 frames per second, then we need 300 frames for a 10 second animation. To find the frame rate we want to pull from the video, we take 300 frames divided by 90 seconds, which gives us a frame rate of 3.33 fps.

Now that we have chosen the frame rate, let's look at the command:

avconv -i /path/to/rosesblooming.mp4 -r 3 -vsync 1 /path/to/rosesblooming%03d.png

Of course, if you are creating an animated GIF, you will use the same command with a .gif extension. Now you should have a collection of PNG and/or GIF images extracted from your video.

Putting together an animated GIF

Now when we create the animated GIF, gifsicle takes a delay in centiseconds (or hundredths of a second) rather than a frame rate. So a frame rate of 30 fps is equivalent to 1 second divided by 30 and multiplied by 100, or about 3 centiseconds.

Here is the command:

gifsicle -d 3 -l /path/to/rosesblooming*.gif > /path/to/rosesblooming.gif

Putting together an animated PNG

When we create the animated PNG, apngasm takes a delay as two integers composing a fraction of a second, so if we have chosen a frame rate, the first integer is one and the second is the frame rate.

Here is the command:

apngasm /path/to/rosesblooming.png /path/to/rosesblooming*.png 1 30

Creating a thumbnail in an animated PNG

The APNG format allows you to specify that the first frame will be skipped during the animation so it is only shown in viewers that don't support animation. To those viewers, the APNG we just created with look like a bunch of leaves. If we want them to see the fully opened roses instead, copy the last frame to /path/to/rosesblooming000.png and add the /f option to the command, like this:

apngasm /path/to/rosesblooming.png /path/to/rosesblooming*.png 1 30 /f

Looping

The above commands create animations that repeat indefinitely. This is the default for apngasm, for gifsicle the -l option specifies this behavior. If you want the animation to play through only once, you can just omit the -l for gifsicle since this is the default, but for apngasm you will add /l1 to specify this. For apngasm, you can use any number in place of 1 to play through a given number of times. For gifsicle, the -l option will take a number as well, but it is separated by a space.

Conclusion

Now you should have all of the tools you need to create your own animated GIF and PNG images. And you can always learn more by reading the documentation for these tools.

Sunday, September 8, 2013

Installing APNG Assembler (apngasm) on Debian Wheezy

Why you would use animated PNG instead of GIF

If you are reading this post, it is likely you may already know the virtues of APNG, but in case you've found this an aren't sure let me give a quick explanation. While animated PNGs are not as widely supported as animated GIFs, they are technically superior. GIF files support only 256 colors, while PNG supports 16,777,216. PNG files support alpha transparency, which means that parts of the image can be semi-transparent. With GIF files, a pixel is either completely transparent or completely opaque, which results in jagged outlines on images with transparency when the background is unknown. You can see the differences for yourself with this demonstration.

Unfortunately, as previously mentioned, support for APNG is somewhat limited. It was developed by Mozilla and has been supported by Firefox since 3.0. Opera supported it from 9.5-12.1, but unfortunately they gave up support for APNG when they moved from their own Presto engine to the Blink (formerly WebKit) engine used by Chrome. It is not natively supported by Chrome, currently the most popular browser in use, but there is an extension that will add support for APNG.

So, if you want the widest support, you may still want to use an animated GIF. But if you want quality, you need APNG and you can suggest your users try Firefox or the APNG extension for Chrome.

Installing APNG Assembler on Debian

APNG Assembler, or apngasm on the command-line, is a simple tool for creating APNGs from a series of PNG files. However, you might notice that it is not available in the official Debian repositories for Wheezy. The project has a Linux binary, but it didn't work for me on Debian Wheezy. However, building it from source is incredibly simple. Go to the project files on sourceforge, select the latest version, and download apngasm-x.x-src.zip. Then use the following commands (these work for 2.7, adjust accordingly if using a newer version):

unzip apngasm-2.7-src.zip
make
sudo cp apngasm /usr/local/bin


Now apngasm is installed and ready for use. (Note that you must be in the sudo group to use the last command.)

Usage

APNG Assembler doesn't come with a man page, but the command is documented in the readme.txt that comes with the source. Nevertheless, here is a quick overview.

 In order to make an animated PNG, you need a series of PNG images whose names end with sequential numbers, like this:

frame01.png
frame02.png
frame03.png


and so forth.

Basic usage is:

apngasm animation.png frame*.png

This produces an animated PNG that loops at 10 frames per second forever. If you want to change the delay between frames, you add two number to the command that represent a fraction of a second delay time. So, to produce an animated PNG that loops at 25fps (1/25 second delay) you would use:

apngasm animation.png frame*.png 1 25

If you what the animation to loop a limited number of times and then stop, you can use the /l options like this:

apngasm animation.png frame*.png /l2

This will cause the animation to play through twice, and then stop.

For backwards compatibility, animated PNGs can be displayed as a regular, non-animated PNG, but only the first frame will be shown. However, animated PNG also has a feature that allows you to skip the first frame. This way, you can use the first frame to display a thumbnail to non-supporting applications while omitting it from the animation. This thumbnail could be a single frame from the middle or end of the animation, possibly with a message informing the viewer that the image contains an animation their browser or viewer is not able to display. Once you have created this thumbnail as your first frame, simply add the /f option:

apngasm animation.png frame*.png /f

Now the first frame will be displayed for viewers that don't support APNG, but omitted from the animation.

Now you are ready go and fill the internet with much better animated images!

Protip #1

Some of you already do this and will think it is comically obvious. But someone out there will read this and think, "Oh, wow... that is such a great idea!"  and it will save them many a headache in the future. That person will achieve enlightenment.

Protip #1:

Whenever you are working on a computer and come across some oddity or have to configure things in an unusual or non-obvious way to make it work, make a note of it and document this information for future use. This will keep you from spinning your wheels trying to solve the same strange problem again later on (you don't think at the time that you will forget this stuff, but you will). One way to do this is to file this information away wherever you store important documents and information. This particularly works well if you maintain a lot of machines and want to keep your records in a centralized location. A simple alternative method (one I really like) is to simply write the information on a note card or something of that nature and put it inside of the case. That way, you can always find it when you are working on that machine.

Upon hearing this, the reader was enlightened.1