Converting an image to ASCII image in Python

Converting an image to ASCII art involves transforming pixel brightness values into corresponding ASCII characters. This creates a text-based representation of the original image using characters like #, @, *, and . to represent different shades.

Required Library

We'll use the Pillow library for image processing −

pip install Pillow

ASCII Character Set

First, define the ASCII characters arranged from darkest to lightest −

ASCII_CHARS = ['#', '?', '%', '.', 'S', '+', '.', '*', ':', ',', '@']
print("ASCII characters from dark to light:", ASCII_CHARS)
ASCII characters from dark to light: ['#', '?', '%', '.', 'S', '+', '.', '*', ':', ',', '@']

Image Processing Functions

Resizing the Image

Resize the image to a manageable width while maintaining aspect ratio −

from PIL import Image

def resize_image(image, new_width=25):
    (original_width, original_height) = image.size
    aspect_ratio = original_height / float(original_width)
    new_height = int(aspect_ratio * new_width)
    resized_image = image.resize((new_width, new_height))
    return resized_image

# Example usage (would work with actual image file)
print("Function defined: resize_image()")
print("Purpose: Maintains aspect ratio while resizing")
Function defined: resize_image()
Purpose: Maintains aspect ratio while resizing

Converting to Grayscale

Convert the colored image to grayscale for easier processing −

def convert_to_grayscale(image):
    return image.convert('L')

print("Function defined: convert_to_grayscale()")
print("Converts image to grayscale using 'L' mode")
Function defined: convert_to_grayscale()
Converts image to grayscale using 'L' mode

Pixel to ASCII Conversion

Map pixel brightness values to ASCII characters −

ASCII_CHARS = ['#', '?', '%', '.', 'S', '+', '.', '*', ':', ',', '@']

def pixels_to_ascii(image, range_width=25):
    pixels = list(image.getdata())
    ascii_chars = [ASCII_CHARS[pixel_value // range_width] for pixel_value in pixels]
    return "".join(ascii_chars)

# Simulate pixel values
sample_pixels = [0, 50, 100, 150, 200, 255]
sample_ascii = [ASCII_CHARS[pixel // 25] for pixel in sample_pixels]
print("Sample pixel to ASCII mapping:", sample_ascii)
Sample pixel to ASCII mapping: ['#', '?', '.', '+', '*', '@']

Complete ASCII Converter

Here's the complete function that combines all steps −

from PIL import Image
import os

ASCII_CHARS = ['#', '?', '%', '.', 'S', '+', '.', '*', ':', ',', '@']

def resize_image(image, new_width=25):
    (original_width, original_height) = image.size
    aspect_ratio = original_height / float(original_width)
    new_height = int(aspect_ratio * new_width)
    return image.resize((new_width, new_height))

def convert_to_grayscale(image):
    return image.convert('L')

def pixels_to_ascii(image, range_width=25):
    pixels = list(image.getdata())
    ascii_chars = [ASCII_CHARS[pixel_value // range_width] for pixel_value in pixels]
    return "".join(ascii_chars)

def image_to_ascii(image, new_width=25):
    # Resize image
    image = resize_image(image, new_width)
    # Convert to grayscale
    image = convert_to_grayscale(image)
    # Convert pixels to ASCII
    ascii_string = pixels_to_ascii(image)
    
    # Split into lines
    ascii_lines = [ascii_string[i:i + new_width] for i in range(0, len(ascii_string), new_width)]
    return "\n".join(ascii_lines)

def convert_image_to_ascii(image_filepath, output_width=50):
    try:
        image = Image.open(image_filepath)
    except Exception as e:
        print(f"Unable to open image file: {image_filepath}")
        print(f"Error: {e}")
        return
    
    # Convert to ASCII
    ascii_art = image_to_ascii(image, output_width)
    
    # Save to text file
    output_file = os.path.splitext(image_filepath)[0] + '.txt'
    with open(output_file, 'w') as f:
        f.write(ascii_art)
    
    print(f"ASCII art saved to: {output_file}")
    return ascii_art

# Example usage (requires actual image file)
# convert_image_to_ascii('button.jpg', 50)

How It Works

The conversion process follows these steps:

  1. Resize: Reduce image dimensions for manageable ASCII output
  2. Grayscale: Convert to single channel (brightness values 0-255)
  3. Map: Divide brightness by range_width to get ASCII character index
  4. Format: Split the ASCII string into lines matching image width
  5. Save: Write the ASCII art to a text file

Customization Options

You can modify several parameters for different effects −

# Different ASCII character sets
detailed_chars = ['@', '#', 'S', '%', '?', '*', '+', ';', ':', ',', '.', ' ']
simple_chars = ['#', '*', '.', ' ']

print("Detailed character set:", len(detailed_chars), "characters")
print("Simple character set:", len(simple_chars), "characters")

# Different widths affect detail level
widths = [25, 50, 100]
print("Width options for different detail levels:", widths)
Detailed character set: 12 characters
Simple character set: 4 characters
Width options for different detail levels: [25, 50, 100]

Conclusion

ASCII art conversion transforms images into text by mapping pixel brightness to characters. The process involves resizing, converting to grayscale, and mapping brightness values to ASCII characters. Adjust the width parameter and character set to control the output detail and style.

Updated on: 2026-03-15T18:09:39+05:30

693 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements