In this post, we’ll account for a method for converting animated GIFs to an ASCII representation of the animated GIF.

ASCII art is as old as the internet. It used to be used to represent images before computers supported images. An ASCII image is a representation of an image as a collection of specific ASCII characters, which look like the original image. For example, here is an ASCII image of Che Guegevara:

An animated GIF is collection of images, which are iterated through upon playing. This means we’ll have to create a GIF file interpreter (or find one), and construct a method for converting an image to its ASCII representation and save them as a .GIF again.

We’ll segment an image into a number of subblocks, each which get to represent a single ASCII character. Then we’ll find the density of the subblock and find the best matching ASCII character (ie. one with the same density). This means we’ll find the density (i.e. points per area covered) of all 128 ASCII characters (excluding the 32 first, though, they are not drawable), and calculate the percentage of the highest density.

We’ll do the same for all subblocks. We’ll first convert the subblock to greyscale, using a contrast-preserving conversion. This means that the brightness D of a point (R, G, B) is D = 0.21R + 0.71G + 0.07B. This conversion is derived from the fact that the human eye detects changes in the green channel better than the red and blue channel. Next up, we’ll find the percentage density of each subblock and find the best matching ASCII character and add it to an array. We have done this conversion on a picture of Barack Obama:

This is perfectly satisfying for our purposes, and we conclude our method is successful. Next up, we’ll extend our program to allow .GIFs. We find a .GIF file handler on the internet, and apply the above process to every image of the 20th Century Fox intro, yielding:

Click the image to animate, if it doesn’t do so by itself.

Hey, this is pretty nice! It seems we have a working program. However, there is one thing I’m not satisfied with – it treats the individual subblocks as a single color. This means that a subblock shaped like a plus-sign might not be replaced by a plus-sign, if its density doesn’t match. It takes in account the density, but not the shape of the subblock. For a future project, I might try represent each subblock by a matrix, and find a suitable metric that takes in account the density as well as the shape, which I hypothesise will give a better image.



Sidenote: I made a Reddit post on this program, which, at the time of writing this post, is the 8th most upvoted post on the /r/compsci subreddit. Link: http://www.reddit.com/r/compsci/comments/1p1fvv/so_i_made_a_gif_to_ascii_gif_converter/

Gallery: