⚡ Python Power Shots – 🔡 ASCII Art Converter
Posted On: October 27, 2025
Description:
📌 Introduction
Did you know your Python scripts can turn images into art?
This Power Shot uses Pillow (PIL) to convert any image into ASCII characters — bringing out a creative, retro terminal-style effect.
You can use it to create text-based art, profile banners, or just explore a fun intersection between programming and design.
🔎 Explanation
- The script loads an image and converts it to grayscale, so each pixel has a brightness value between 0 and 255.
- Then, each pixel’s brightness is mapped to an ASCII character from a predefined ramp (@%#*+=-:. ).
- The image is resized to match the proportions of terminal text (characters are taller than they are wide).
- Finally, it prints the ASCII lines or saves them into a .txt file — ready to share or display in the console.
✅ Key Takeaways
- 🎨 Convert images into text-based art using only Python.
- ⚙️ Works offline with just the Pillow library.
- 🧠 Customize width, charset, and invert options for different styles.
Code Snippet:
# Import PIL for image loading and processing
from PIL import Image
# Import os for optional path handling
import os
# --- Configuration you can tweak ---
IMAGE_PATH = "input.jpg" # <-- Change this to your image path (PNG/JPG)
OUTPUT_TXT = "ascii_art.txt" # Set to None to skip saving to file
TERMINAL_WIDTH = 100 # Target text width (characters)
INVERT = False # True = dark chars on light areas; False = normal mapping
# ASCII ramp from dark (index 0) to light (last index).
# You can try denser ramps for more detail.
ASCII_CHARS = "@%#*+=-:. " # 10 levels; swap order or use reversed for invert
def image_to_ascii(image_path: str,
width: int = 100,
invert: bool = False,
charset: str = ASCII_CHARS) -> str:
"""
Convert an image to ASCII art and return it as a multi-line string.
Args:
image_path: Path to input image (JPG/PNG).
width: Output character width (height is auto-calculated).
invert: If True, flips the brightness mapping.
charset: Characters from darkest -> lightest.
Returns:
A string containing the ASCII art (lines separated by '\n').
"""
# 1) Load image and convert to grayscale
img = Image.open(image_path).convert("L") # "L" = 8-bit grayscale
# 2) Compute resized dimensions.
# Terminal text cells are taller than they are wide, so we correct aspect ratio.
# The factor ~0.45 works well for many monospace fonts.
orig_w, orig_h = img.size
aspect_ratio = orig_h / orig_w
new_w = max(10, int(width))
new_h = max(5, int(aspect_ratio * new_w * 0.45))
img = img.resize((new_w, new_h))
# 3) Optionally invert the character ramp
chars = charset[::-1] if invert else charset
n = len(chars)
# 4) Map each pixel (0-255) to a character index
# index = pixel/255 * (n-1), rounded down
pixels = img.getdata()
mapped = [chars[int(p / 255 * (n - 1))] for p in pixels]
# 5) Join rows
lines = ["".join(mapped[i:i + new_w]) for i in range(0, len(mapped), new_w)]
return "\n".join(lines)
def main():
# Validate source image path
if not os.path.exists(IMAGE_PATH):
raise FileNotFoundError(f"Input image not found: {IMAGE_PATH}")
ascii_art = image_to_ascii(
image_path=IMAGE_PATH,
width=TERMINAL_WIDTH,
invert=INVERT,
charset=ASCII_CHARS
)
# Print to terminal
print(ascii_art)
# Optionally save to a text file
if OUTPUT_TXT:
with open(OUTPUT_TXT, "w", encoding="utf-8") as f:
f.write(ascii_art)
print(f"\n✅ ASCII art saved to: {OUTPUT_TXT}")
if __name__ == "__main__":
main()
Link copied!
Comments
Add Your Comment
Comment Added!
No comments yet. Be the first to comment!