This project is split into 3 parts: CLI, API and WEB versions. All of these use roughly the same Backend. You can find more details in readme
located in each part's repo.
- If you want to use user-friendly interface, checkout this project's website.
- There is also a CLI version of this project that you can easily download by following the instructions on it's repo.
PROBLEM: Convert image into ascii characters.
SOLUTION: Firstly, we must decide how are we going to treat image. Thankfully to PIL library, we can easily prepare a image by resizing and applying various filters on it. After this process (prepare_image()
function) we can simply turn it into matrix made of pixels using .load()
method. At this point, we can turn each pixel into character. But, how can we decide which pixel corresponds to an character? We know, that every pixel has a color represented in RGB values. By using (R+G+B) /3
formula (avg
) we get approximated brightness value. As the value will always be somewhere in between 0 and 255 (including both points) we know that, brightness of each pixel's brightness can be one of 256 values. This fact lets us build a scale where we split theese 256 values into groups where each group has a corresponding ASCII character. The main built in scale called short
is this set of characters: .:-=+*#%@
. As you can see, every next character takes a little bit more space than previous one. Using fact that, we can get pixel's brightness and roughly represent it as a character, we must build a scale that connects some values into a character. For example, pixel with brightness equal to 0 is completly black and "invisible", so we can treat it exactly as a space character. In fact, we don't have (however, we can) to assign a individual character for every value, but we can assign group of values into one character (as a pixel with brithness equal to 20 looks almost the same as a pixel with brightness level at 28 and by converting image into text, we don't really expect 1:1 quality.) That's where we are going to use simple algorithm for converting normal text (like one in short
scale) into groups of values with associated character. To start, we need to check how much characters do we have to assign. For example, short
scale contains 10
characters. Than we can calculate step
's value by simple division: 256/scale_length
. To ensure, that there will be no floting point value, we will round result of this division and as brightness scale starts from 0, we will add 1 to outcome. Final formula for calculating step
: round(256/scale_length)+1
. Now, we can assign characters to range of numbers in between current step and next step. Using for range_index in range(-1, 256, step)
we can jump by step
numbers up to 256. To group numbers, we can create built in range
object that starts with current value: range_index +1
and leads up to value of next step: range_index + step +1
. And that's how we get dictionary of range: character
values. When we know which brightness values accords to which character, we can finally iterate over each pixel of image, calculate its brightness and get corresponding ASCII character.