3 min

ASCII Art Generation

I use arch btw

ASCII art is one of my favorite forms of art. I love how simple it is, but at the same time, how complex it can be. I've always been fascinated by how I could go onto a website, drop an image, and have it spit out the image using a bunch of characters. How does it do it? How does it know what characters to use? A few days ago, I decided to try to learn how to make a ASCII art generator. It's been in the back of my mind for over a decade, but I never had the skills to do it until now.

How It Works

The process of generating ASCII art was more simple than I thought. It takes an image and maps each pixel to a character based on its brightness. The darker the pixel, the "darker" the character would be used. For example, given the following characters:

Note that there is a space at the end
@%#*+=-:.

@ would be used for the darkest pixels, while a (space) would be used for the lightest pixels.

Brightness Mapping

In order to map one of the charactgers above to a pixel, I needed to find a way to calculate the brightness of each pixel. There are many ways to do this, but the formula I chose was Relative Luminance.

L = 0.2126 * R + 0.7152 * G + 0.0722 * B;

Where R, G, and B are the red, green, and blue values of the pixel. Using this formula would give me a value between 0 and 255, which I could then use to map it to one of the characters above.

Character Mapping

In order to map the brightness value to a character, I divided the brightness value by 255 and multiplied it by the length of the character set. This would give me an index that I could use to get the character from the character set.

const index = Math.floor(
  Math.max(0, Math.min(1, luminance / 255)) * (chars.length - 1),
);

Results

Conclusion

I'm extremely happy with how this project turned out and kind of glad it wasn't as hard as I thought it would be. It was fun learning about things like luminance, ImageData, and why characters were mapped the way they were. If you want to try it out for yourself, you can visit the website here.

To end things off, here's another Miku: