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