63

There are some nice free "image to ASCII art" conversion sites like this one: ASCII-art.org

How does such an image conversion algorithm work?

                         ,                     
                     .   W    ,                
                     W   W    @                
                     W  ,W    W                
                  ,  W, :W*  .W  .             
                  #  WW @WW  WW  #             
                  W  WW.WWW  WW: W             
                  W. WW*WWW# WW@ W             
               * :WW.WWWWWWW@WWW@W  #          
              +* #WW#WWWWWWWWWWWWW# W          
              W# @WWWWWWWWWWWWWWWWW W          
              WW WWWWWWWWWWWWWWWWWW W          
              WW WWWWWWWWWWWWWWWWWW@W#         
             ,WW.WWWWWWWWWWWWWWWWWWWWW         
              WW@WWWWWWWWWWWWWWWWWWWWW         
            : WWWWWWWWWWWWWWWWWWWWWWWW :       
            @ WWWWWWWW@WWWWWWW@@WWWWWW.        
            W*WWWWWW::::@WWW:::::#WWWWW        
            WWWWWW@::   :+*:.   ::@WWWW        
            WWWWW@:*:.::     .,.:.:WWWW        
            @WWWW#:.:::.     .:: #:@WWW        
            :WWW@:#. ::     :WWWW:@WWWW        
             WWW#*:W@*@W     .   W:#WWW        
            #WWWW:@      ::   ::  *WWWW        
            W@WW*W  .::,.::::,:+  @@WW#,       
            WWWW## ,,.: .:::.: .  .WWW:,       
            @WWW@:   W..::::: #.  :WWWW        
             WWWW::  *..:.  ::.,. :WWWW        
             WWWW:: :.:.:   :  :: ,@WW@        
             WWWW:  .:,  :  ,,     :WW,        
             .: #         :  ,     : *         
              W +    .,  :::  .,   : @         
              W ::                .: W         
           @,,,W:.  ,, ::*@*:,  . :@W.,,@      
         +.....*: : : .#WWWWW:  : .#:....+,    
        @...:::*:,, : :WWWWWWW, ,  *::::..,#   
      :...::::::W:,   @W::::*W.   :W:::::...#  
     @@@@@@@@@@@W@@@@@W@@@@@@W@@@@@W@@@@@@@@@@:

Ali Afshar
  • 40,967
  • 12
  • 95
  • 109
splattne
  • 102,760
  • 52
  • 202
  • 249

4 Answers4

106

The big-picture-level concept is simple:

  1. Each printable character can be assigned an approximate gray-scale value; the "at" sign @ obviously is visually darker than the "plus" sign +, for example. The effect will vary, depending on the font and spacing actually used.

  2. Based on the proportions of the chosen font, group the input image into rectangular pixel blocks with constant width and height (e.g. a rectangle 4 pixels wide and 5 pixels high). Each such block will become one character in the output. (Using the pixel blocks just mentioned, a 240w-x-320h image would become 64 lines of 60 characters.)

  3. Compute the average gray-scale value of each pixel block.

  4. For each pixel block, select a character whose gray-scale value (from step 1) is a good approximation of the pixel block average (from step 3).

That's the simplest form of the exercise. A more sophisticated version will also take the actual shapes of the characters into account when breaking ties among candidates for a pixel block. For example, a "slash" (/) would be a better choice than a "backward slash" (\) for a pixel block that appears to have a bottom-left-to-upper-right contrast feature.

joel.neely
  • 30,725
  • 9
  • 56
  • 64
  • can you give a sample list of character in the order of darkness. doesn't matter which character. I just want to draw quick contour plots in terminal. 10 would be ok, more is better (http://stackoverflow.com/questions/15335412/rank-ascii-characters-by-intensity-darkness-lightness) – kirill_igum Mar 15 '13 at 03:24
  • 1
    You would need to experiment with the fonts you plan to use, but here's a (9-level) scale from the article mentioned in another comment below (http://www.codeproject.com/Articles/20435/Using-C-To-Generate-ASCII-Art-From-An-Image): BLACK = "@"; CHARCOAL = "#"; DARKGRAY = "8"; MEDIUMGRAY = "&"; MEDIUM = "o"; GRAY = ":"; SLATEGRAY = "*"; LIGHTGRAY = "."; WHITE = " "; You might add "W" between "#" and "@", for example, but the actual font in use by your terminal may require adjustment. – joel.neely Mar 16 '13 at 12:15
  • @splattne Here an [simple example of mine approaches for this task in C++](http://stackoverflow.com/a/32987834/2521214) the first one is the same as this answer – Spektre Oct 07 '15 at 14:37
  • 2
    Thanks for this explanation! Note I wrote a detailed tutorial based on your detailed post: https://www.jonathan-petitcolas.com/2017/12/28/converting-image-to-ascii-art.html :) – Jonathan Petitcolas Dec 28 '17 at 10:28
20

aalib (last release in 2001) is an open source ASCII art library that's used in applications like mplayer. You may want to check out its source code to see how it does it. Other than that, this page describes in more detail about how such algorithms work.

Brian Burns
  • 20,575
  • 8
  • 83
  • 77
codelogic
  • 71,764
  • 9
  • 59
  • 54
14

Also you can take a look at libcaca (latest release 2014), which acording to their website has the following improvements over aalib:

  • Unicode support
  • 2048 available colours (some devices can onlyhandle 16)
  • dithering of colour images
  • advanced text canvas operations (blitting, rotations)
Brian Burns
  • 20,575
  • 8
  • 83
  • 77
daniels
  • 18,416
  • 31
  • 103
  • 173
  • :P yes but disregarding the icon and the name of the lib, the code doesn't stink. and btw from what i know VLCPlayer uses this lib for its ascii output. One should try to see a movie in ascii :)) it's quite fun – daniels Dec 28 '08 at 19:11
  • and also getting feed and rendering as ascii from the webcam works – daniels Dec 28 '08 at 19:12
8

I found this CodeProject article written by Daniel Fisher containing a simple C# implementation of a image to ASCII art conversion algorithm.

These are the steps the program/library performs:

  1. Load the Image stream to a bitmap object
  2. Grayscale the bitmap using a Graphics object
  3. Loop through the image's pixels (because we don't want one ASCII character per pixel, we take one per 10 x 5)
  4. To let every pixel influence the resulting ASCII char, we loop them and calculate the brightness of the amount of the current 10 x 5 block.
  5. Finally, append different ASCII characters based for the current block on the calculated amount.

Quite easy, isn't it?

BTW: In the comments to the article I found this cool AJAX implementation: Gaia Ajax ASCII Art Generator:

[...] I felt compelled to demonstrate it could easily be done in a standardized set of web technologies. I set out to see if I could find some libraries to use, and I found Sau Fan Lee's codeproject article about his ASCII fying .NET library.

P.S.: Lucas (see comments) found another CodeProject article.

splattne
  • 102,760
  • 52
  • 202
  • 249
  • here's another C# sample in CodeProject: http://www.codeproject.com/KB/recipes/ASCII_Imager.aspx – Lucas Feb 18 '09 at 12:33