AsciiArt

From IPRE Wiki
Jump to: navigation, search

Lucy2.jpg Lucy-ascii2.gif

As an homage to past days where high resolution displays and printers were rare, we will create a myro program that displays the robot's images using text characters rather than pixels. This is called ASCII Art. Let's write a simple program to create an ASCII image as a text file. You could also write the image as an HTML file to view in a web browser, but this example uses a simple text file.

The Program

We import the myro module, initialize our robot, and grab a color image from the camera. We will save the picture to a jpeg file to later compare with our ASCII art masterpiece.

from myro import *  
initialize('/dev/tty.scribbler5844')
p = takePicture()
show(p)
savePicture(p, 'out.jpg')

Let's open up our ASCII art text file:

f = open('out.txt', 'w')

There are a variety of ways to create ASCII Art, but in this example we'll treat dark pixels with large/wide characters and bright pixels with small characters. Our alphabet (as a string) from darkest to brightest looks like this:

alphabet = '@MHWRmEBSQKUGgqyp$8XDPFwdbkA&0ZTNhe9654YV*Cnsyza%3OLxo2JufIrc][vt}{71lji?|+)(=;-_!~:/,^.`'

Of course, you could use all different alphabets for example, any of these would work:

alphabet = '@$#zywvutsrqponmlkjihgfedcba?|;+=~:-^*`',. '
alphabet = '@$#ZYXWVUTSRQPONMLKJIHGFEDCBAzywvutsrqponmlkjihgfedcba?|;+=~:-^*`',. '
alphabet = '@MHWRmEBSQKUGgqyp$8XDPFwdbkA&0ZTNhe9654YV*Cnsyza%3OLxo2JufIrc][vt}{71lji?|+)(=;-_!~:/,^.`'

Since our pixels range from 0-255, but our alphabet isn't that big, we'll have to share characters for ranges of pixels. This 'divider' value figures out how many need to share.

divider = 256 / len(alphabet)  + 1

Rather than converting the whole 256x192 image into text, we are going to subsample it, taking every third row, and every other column. You lose some detail in the image, but otherwise the ASCII image would be huge. The ASCII art of lucy above is full resolution with tiny font size. We'll grab the intensity of each pixel (for color we have to convert to gray scale first). Then we figure out where in the alphabet to look based on how brightness or intensity of the pixel. After every row we output a new line ('\n').

 for j in range(0, getHeight(p), 3):
     for i in range(0, getWidth(p), 2):
         pix = getPixel(p, i, j)
         intensity = (getRed(pix) + getGreen(pix) + getBlue(pix)) / 3 
         val = intensity / divider
         f.write(alphabet[val])
       
     f.write('\n')

Finally, we close our text file.

 f.close()


Future Extensions

  1. Invert the ASCII art so that bright pixels use large characters, and dark pixels use small characters.
  2. Create the ASCII art as an HTML file to be viewed in a browser. (You might want to preformat the text in the HTML as well as using an extremely small font.)
  3. Modify this program to continuously stream ASCII images to your screen rather than working on one image.