![]() ![]() This kills two birds with one stone, preventing the bad matching and performance limitation issues. A better approach - weighted matching with gradient and lightnessįor a start, I switched back to a monospaced font. ![]() On the plus, you could theoretically copy this into a Word document and be left with your rocket unharmed. While this can make some light areas light, it doesn’t really respect the shape of the rocket and leaves large areas blank for unknown reasons. Here is the rocket with this approach and Calibri. On the other hand, this approach does have the advantage of supporting variable width fonts. This can result in small individual images taking minutes to make. This requires Pillow’s font.getlength function, which is very slow as it has to draw out characters onto a canvas to get their length. As only a small amount of space is added for a new character each time, many wider characters that may have been better fits will never be tested against the space. For example, lines that would cross over the top of the cell (‾) would have no good matches with my character set, and the best character that would end up being used was the space. It does not respect the shape of the image.However, this approach had many limitations that I found out at various times. # slice the bit we need and sum the bit we dontĭraw_finished.text((0, y), chars, (0,), font=font) # now calculate the difference from grayscale If (newlen <= x) and (arr.shape < (x - last_ending)): I would continually add a small amount of “extra room” for the next character, and each time I did this, I would add the character has the smallest pixel wise squared difference from the original image.įor y in range(0, y_size - line_height, line_height): This allows me to use fonts that aren’t monospaced. Instead, I decided to split the image into rows, and in each row, I would try to come up with a list of characters that matches it as well as possible. I decided I would abandon the cells altogether. My next idea was not successful, but I’ll document it here anyway, maybe as a warning to any other ambitious nerds. This means that if the characters are small enough, we won’t be able to tell what they are and will just end up seeing an image quite close to the grayscale approaches A failing approach - matching by pixel difference However, our eyes also average out brightnesses. Similarly, we can do this for each character, and put the character with the most similar percentage darkness in each cell. We can work out this percentage darkness by averaging out the darknesses of all the pixels in each cell. One very simple (but not particularly interesting) way to approach this problem is by trying to divide the grid into lots of little monospaced rectangles (one for each character).Įach cell will have a percentage darkness. Let’s get some ideas out of the way first. Throughout this article, I’ll be using this image of a rocket as an example.Īs ASCII characters do not have colour, it makes sense to only deal with the grayscale version of the image, which is also above. My final approach uses the Sobel operator and convolutions utilising complex numbers to create ASCII art that respects the edges of an original photo.Īs always, skip to the end to see the end result if you are non-technical. For a while now, I’ve wanted to automatically create ASCII art, and I’ve ended up with a couple of approaches to the problem, and I’ve even managed to make some videos of memes with it.
0 Comments
Leave a Reply. |
AuthorWrite something about yourself. No need to be fancy, just an overview. ArchivesCategories |