DEV Community

Anurag Rana
Anurag Rana

Posted on • Originally published at pythoncircle.com on

Generating ASCII art from colored image using Python

image source: https://www.pythoncircle.com

Adding a new script to the Python Script series. In this article, we will see how to convert the colored image to ASCII art.

Dependecies:

You will need to install pillow python package. It is recommended that you create a virtual environment using python3 if not created already.

Once virtual environment is activated use command pip install pillow to install the package.

Steps:

We are performing below actions to generate the ascii art from image.

  • Get an image path as a command line argument.
  • Open the image from the provided path.
  • Calculate the aspect ratio.
  • Resize the image. Here we are taking new width as 120 pixels. Adjusting the new height as per aspect ratio.
  • Convert the image into greyscale format.
  • Get all the pixels of image. Replace pixles with intentsity in a defined range with a character from list.
  • Print image and save to text file.

Code:

import sys
from PIL import Image

# pass the image as command line argument
image_path = sys.argv[1]
img = Image.open(image_path)

# resize the image
width, height = img.size
aspect_ratio = height/width
new_width = 120
new_height = aspect_ratio * new_width * 0.55
img = img.resize((new_width, int(new_height)))
# new size of image
# print(img.size)

# convert image to greyscale format
img = img.convert('L')

pixels = img.getdata()

# replace each pixel with a character from array
chars = ["B","S","#","&","@","$","%","*","!",":","."]
new_pixels = [chars[pixel//25] for pixel in pixels]
new_pixels = ''.join(new_pixels)

# split string of chars into multiple strings of length equal to new width and create a list
new_pixels_count = len(new_pixels)
ascii_image = [new_pixels[index:index + new_width] for index in range(0, new_pixels_count, new_width)]
ascii_image = "\n".join(ascii_image)
print(ascii_image)

# write to a text file.
with open("ascii_image.txt", "w") as f:
 f.write(ascii_image)

If you are getting an elongated image in terminal, you can adjust the height accordingly. I am generating new_height using formula new_height = aspect_ratio * new_width * 0.55.

Statement list(img.getdata()) returns the list intensity of all pixels. Value of intensity will be between 0 to 255. Lower the value, darker the color. That is why we have characters in char list arranged from higher intensity to lower intensity.

Value of pixel//25, where 25 is the intensity range for one character, can be between 0 to 11 i.e why there are 11 characters in charslist. You may keep more characters in the list, let's say 16 characters and then keep the range size as 17.

Line new_pixels = [chars[pixel//25] for pixel in pixels] replaces the pixels with intensity from 0 to 25 with first character from chars list and 26 to 50 with seconds character from chars list and so on.

In the last lines we break the string into a matrix and print it.

How to use script:

To run the script use below command.

python3 script_name path_to_image

python3 image_to_ascii.py /home/Downloads/image.png

Code is available on Github.

More from https://www.pythoncircle.com

Discussion (0)