Creating an image to ascii parser on C
Fri Aug 08 2025
Take an image and convert it into ASCII characters, this was one of my first challenges in my first semester of undergrad and I failed. So I took it up again but 3 years later.
I remember when I was a kid, my fathers bought two drawings made with a typewriter, a fall and a horse, I really like it this type of art. But that was stuck on my memories. But more recently, I was scrolling on the v.tulv.in gallery, and I found this beatiful image:

And my curiosiry woke up. So here you are, reading how I build a image to ascii parser from scratch. In add I was looking for an excuse to code in C again and performing a lot of computation was the perfect excuse to make it. So lets go!
Setup the ground
meson is a compiler with too many porpuses, I used it to build and app with GTK4 and it was extremly fast. For this reason I build my project with it. Is too easy to use and I really thanks that beacuse C is very complex to understand. My configuration goes something like this.
The next step is think how to process images to convert them into ascii art, later I’ll explain how to colorize the ascii art. If we create a program that recieve an image we need to understand that image as a 2D array (a matrix) of 3 or 4 values (channels) in PNG images, so we need to scale the image to a version of the image with lower resolution. This is important because if we create an ascii art per each pixel in the image we’ll get a 10 times bigger image than the original one. That’s why I setted up by default an automatic reduction by 0.6 porcent of the original image size, BUT the user can select the output size (width and height).
Then, once we reduce the image, we need to calculate a unique value for every pixel in the image. For this remember that each pixel exists 4 values within (R, G, B, Alpha), so in this case I calculate the average of those values: . In the case of PNG images we need to check if Alpha value is different of 0. That’s not the value of the color that we’ll use in the final image, this value represents the character that will correspond for that pixel in the following character gradient: render_gradient[] = "$&8WMB@%#*+=-:.' ". This process generates a .txt file with a plain text version of the original image.

As we see, the result is still in blank, no colors, so we need to save the last values from the pixels that we used to get the last image. This values will be the colors of the characters on the rendered final image. To achieve this I used the STB lib, in special this image utility.
So we got the following result:
If you are sharp-eyed, maybe already noticed that the characters gradient is different from the one in the first image, that’s why I observed that in some images the first gradient was no visually coherent, so I select a different gradient for rendering. A gradient that could cover more pixeles in the image and help the visualization of colors.
In add I added a TUI (terminal UI) to select others fonts and change the background color. All the code is free in the following repository.
ascii-parser
A image parser that converts images to ASCII characters, capable of generating both text files and rendered PNG images.
C