This is just a simple script that takes an image and renders it as a grid of ASCII characters in the console. The character chosen depends on the brightness of each pixel in the image: the following sequence (from densest (brightest) to least dense) is used:


The rendered image contrast can be controlled (to some extent) by setting the value of the contrast variable in the range -10 to +10. A default width of 100 characters is used can be passed as an optional command line argument after the original image filename, e.g.

python girl-with-a-pearl-earring.png 120

The following images were produced from the files saturn.jpg and girl-with-a-pearl-earring.png.

Saturn as ASCII art

The girl with the pearl earring as ASCII art

import sys
import numpy as np
from PIL import Image

# Contrast on a scale -10 -> 10
contrast = 10
density = ('$@B%8&WM#*oahkbdpqwmZO0QLCJUYXzcvunxrjft/\|'
           '()1{}[]?-_+~<>i!lI;:,"^`\'.            ')
density = density[:-11+contrast]
n = len(density)

img_name = sys.argv[1]
    width = int(sys.argv[2])
except IndexError:
    # Default ASCII image width.
    width = 100

# Read in the image, convert to greyscale.
img =
img = img.convert('L')
# Resize the image as required.
orig_width, orig_height = img.size
r = orig_height / orig_width
# The ASCII character glyphs are taller than they are wide. Maintain the aspect
# ratio by reducing the image height.
height = int(width * r * 0.5)
img = img.resize((width, height), Image.ANTIALIAS)

# Now map the pixel brightness to the ASCII density glyphs.
arr = np.array(img)
for i in range(height):
    for j in range(width):
        p = arr[i,j]
        k = int(np.floor(p/256 * n))
        print(density[n-1-k], end='')
Current rating: 4.2


Comments are pre-moderated. Please be patient and your comment will appear soon.

There are currently no comments

New Comment


required (not published)