Turning your images to ASCII Art using Python

Filed Under: Python
Images To ASCII Art

In this tutorial, we will learn how to convert any image to ASCII art using the Python programming language. I’m sure you have heard of ASCII art which is a graphic design technique that uses printable ASCII characters to display images. Look at the image below for an example.

ASCII Art Illustration
ASCII Art Illustration

Now that we are clear with what we aim to do by the end of this tutorial. Let’s not waste any more time and begin the code implementation.

Creating ASCII Art From An Image Using Python

In this section, you will learn how to generate ASCII art from an image using Python.

Loading an Image

The first and foremost step is to load the image into our program using the PIL library. We will make use of the exception handling to make sure we handle errors beforehand. We will use a flag variable to know if the image is in the system or not.

Recommended Read: Python Exception Handling – Python try-except

import PIL.Image

img_flag = True
path = input("Enter the path to the image field : \n")

try:
  img = PIL.Image.open(path)
  img_flag = True
except:
  print(path, "Unable to find image ")

Resize The Image

We need to resize the image to a smaller width and height so that it doesn’t end up having too large text and create a mess.

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)))

Convert Image to Grayscale

We can use the convert function and pass the option as L for GreyScale image output.

img = img.convert('L')

Create an ASCII Character List

Remember that the ASCII characters are arranged from darkest to lightest, which means for the list shown below the darkest pixel will be replaced with @ and lightest with .. You can change the list according to your preference.

chars = ["@", "J", "D", "%", "*", "P", "+", "Y", "$", ",", "."]

Convert to ASCI Art

To convert the image to ASCII character, we get the pixel value for each pixel in the image and map the respective ASCII character together to form a new string. Now, we use to_greyscale function to convert our image to a GreyScale image and pixel_to_ascii function to convert our image to ASCII art! We will also save the resulting text into a file.

pixels = img.getdata()
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("sample_ascii_image.txt", "w") as f:
 f.write(ascii_image)

The Complete Code

Let’s have a look at the complete code that we just coded in the previous section.

import PIL.Image

img_flag = True
path = input("Enter the path to the image field : \n")

try:
  img = PIL.Image.open(path)
  img_flag = True
except:
  print(path, "Unable to find 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)))

img = img.convert('L')

chars = ["@", "J", "D", "%", "*", "P", "+", "Y", "$", ",", "."]

pixels = img.getdata()
new_pixels = [chars[pixel//25] for pixel in pixels]
new_pixels = ''.join(new_pixels)
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)

with open("ascii_image.txt", "w") as f:
 f.write(ascii_image)

Some Sample Outputs

ASCII Art Sample Output 1
ASCII Art Sample Output 1
ASCII Art Output 2
ASCII Art Output 2

Conclusion

Go ahead and try this exercise out with a lot of different characters and see the results for yourself. You might find some really interesting results too! Let us know in the comments below for which one worked best for you.

close
Generic selectors
Exact matches only
Search in title
Search in content