Project 2: ASCII Art Machine 🖼️¶

Difficulty: 🟢 Beginner

Run cells top to bottom. Each step builds on the previous one and saves real files under outputs/ascii_art_machine/.

← Back to index

Description¶

Turn any image into retro terminal-style ASCII art saved as a .txt file you can print or share.

Libraries & Modules¶

  • PIL.Image
  • Built-in: string (character ramp)

Python Concepts You'll Practice¶

Nested loops, luminance math, reading/writing text files

🎛️ Parameter Variations¶

  • ASCII_WIDTH — 40 (blocky) vs 120 (detailed)
  • CHARS — try "@%#*+=-:. " or "█▓▒░ " for different moods
  • Replace the sample image path with your own photo
In [1]:
# Install dependencies for this project (safe to re-run)
import sys
!{sys.executable} -m pip install pillow numpy matplotlib wordcloud qrcode[pil] python-barcode fpdf2 jinja2 folium plotly pandas scipy ipywidgets -q
Skipping pip install (already installed)
In [2]:
# Interactive Jupyter setup — run this cell first
%matplotlib inline

from pathlib import Path
from IPython.display import display, Image as IPImage, HTML, Markdown, Audio, IFrame

OUTPUT_DIR = Path("outputs") / "ascii_art_machine"
OUTPUT_DIR.mkdir(parents=True, exist_ok=True)
print(f"✅ Outputs folder: {OUTPUT_DIR.resolve()}")
✅ Outputs folder: C:\Users\Hansel Yan\Projects\CodeItAll\outputs\ascii_art_machine

Step 1 — Create a sample image (or skip if you have your own)¶

In [3]:
from PIL import Image, ImageDraw

sample = Image.new("RGB", (200, 200), (30, 30, 40))
d = ImageDraw.Draw(sample)
d.ellipse([30, 30, 170, 170], fill=(255, 200, 80))
d.rectangle([60, 100, 140, 180], fill=(100, 180, 255))
sample_path = OUTPUT_DIR / "ascii_source.png"
sample.save(sample_path)
display(sample)
No description has been provided for this image

Step 2 — Convert pixels to ASCII characters¶

In [4]:
# 🎛️ TWEAK THESE
ASCII_WIDTH = 80
CHARS = "@%#*+=-:. "  # dark → light

img = Image.open(sample_path).convert("L")  # grayscale
w, h = img.size
ratio = h / w
new_h = int(ASCII_WIDTH * ratio * 0.55)  # 0.55 corrects char aspect ratio
img = img.resize((ASCII_WIDTH, new_h))

lines = []
for y in range(new_h):
    row = ""
    for x in range(ASCII_WIDTH):
        pixel = img.getpixel((x, y))
        idx = int(pixel / 255 * (len(CHARS) - 1))
        row += CHARS[idx]
    lines.append(row)

ascii_art = "\n".join(lines)
print(ascii_art[:500] + ("\n..." if len(ascii_art) > 500 else ""))
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%@@@@@@@@@@@@%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%
...

Step 3 — Save your masterpiece¶

In [5]:
out = OUTPUT_DIR / "ascii_art.txt"
out.write_text(ascii_art, encoding="utf-8")
print(f"Saved {len(lines)} lines to {out}")
Saved 44 lines to outputs\ascii_art_machine\ascii_art.txt

✅ Project complete¶

Check your output folder: outputs/ascii_art_machine/

Next: Project 3: Password Fortress · Index