The makings of an Image to ASCII art converter
Part of the fun of programming is there are many ways to get to an end result. If you give a room full of programmers a task you will likely find a
room full of programs ending up at the same or similiar place all with different routes taken to get there.
The route I took to make the conversion from image to ASCII art was the simpliest I could think of. Instead of complex algorithms, equations and analysis I opted to simply look at
the brightness of each pixel. I would then assign that brightness to a character that represented a given brightness from darkest to
lightest. Here are the steps that I took and I will include the code at the end of the article. The code for the class library will be provided in both VB.Net (Visual Basic) and C#.
If you don't have Visual Studio you can get a free copy of Visual Studio Express at http://www.visualstudio.com/en-us/products/visual-studio-express-vs.aspx.
Source Code Project
The source code is hosted over at CodePlex. The first version has been hosted there since 2008 and I didn't see a reason to move it to Git since I'm the only one working on it (and it's only had one set of changes over 6 years).
Step by Step
The first thing I did was create two string arrays (one ASCII, one Unicode) that had characters in them from darkest to lightest. The higher the position in the array, the lighter the character.
This would allow me to calculate a relative brightness of 1 to 20 and quickly pluck out it's character.
System.Drawing.Bitmap class provides a GetBrightness function that you can call against any pixel with an X/Y coordinate. This class also provides a straighforward simple approach
to using and manipulated images.
Next, I resize the image in proportion. The reason I do this is that a 4,000 pixel piece of ASCII art is probably way to big for most people to view or post places. You have the ability to keep huge resolutions but by default I downsize everything a maximum of 160 pixels in width or height. These can be changed in the
MaxHeight properties to whatever values you see fit. This will also downsize the image in proportion so there isn't any issue with stretching.
I created two readonly properties that would return the output string for the selected type. One referenced the ASCII array and the other the Unicode one. For performance I stored the output into a
System.Text.StringBuilder instead of doing string contactations. If you do any looping with concats your performance will be greatly enhanced with the
For the HTML art I take a simliar approach but instead of calculating the brightness I pull the actual color for each pixel and use it via CSS. This makes for a much larger file because it contains metadata for each pixel but you get a very clear image that's created from text (I also used a b tag instead of a span since it was the smallest one I could think of, the extra characters add up over a lot of pixels).
That's all there is. The source code for the project is provided at the top of this article. I will also include a snippit of how to call the class as well as the class here.