← back to Contact Mailer Ideas
render-slide.py
72 lines
#!/usr/bin/env python3
"""Render a single 1920x1080 PNG slide for a VC pitch video.
Usage: render-slide.py <name> <headline> <score> <output.png>
"""
import sys
from PIL import Image, ImageDraw, ImageFont
if len(sys.argv) != 5:
print("Usage: render-slide.py <name> <headline> <score> <out.png>")
sys.exit(1)
name, headline, score, out = sys.argv[1:5]
W, H = 1920, 1080
img = Image.new("RGB", (W, H), (11, 11, 13))
d = ImageDraw.Draw(img)
# Fonts (system Helvetica)
def font(path, size):
try:
return ImageFont.truetype(path, size)
except Exception:
return ImageFont.load_default()
NAME_FONT = font("/System/Library/Fonts/Supplemental/Arial Bold.ttf", 160)
HEADLINE_FONT = font("/System/Library/Fonts/Supplemental/Arial.ttf", 56)
LABEL_FONT = font("/System/Library/Fonts/Supplemental/Arial Bold.ttf", 28)
FOOTER_FONT = font("/System/Library/Fonts/Supplemental/Arial.ttf", 26)
def center(text, fnt, y, color):
bbox = d.textbbox((0, 0), text, font=fnt)
w = bbox[2] - bbox[0]
d.text(((W - w) // 2, y), text, font=fnt, fill=color)
# Eyebrow label
center("VC PITCH · SCALABILITY", LABEL_FONT, 220, (221, 171, 30)) # accent gold
# Name (big)
center(name, NAME_FONT, 290, (245, 243, 238)) # ink
# Headline (medium gray)
# Word-wrap headline if too wide
def wrap(text, fnt, maxw):
words = text.split()
lines, cur = [], ""
for w in words:
test = (cur + " " + w).strip()
bbox = d.textbbox((0, 0), test, font=fnt)
if (bbox[2] - bbox[0]) > maxw and cur:
lines.append(cur)
cur = w
else:
cur = test
if cur:
lines.append(cur)
return lines
headline_lines = wrap(headline, HEADLINE_FONT, W - 200)
y = 510
for line in headline_lines[:3]:
center(line, HEADLINE_FONT, y, (207, 203, 193))
y += 72
# Score badge
center(f"{score}/40 · OPPORTUNITY-GRADE", LABEL_FONT, 760, (34, 197, 94))
# Footer
center("agentabrams · ideas.agentabrams.com", FOOTER_FONT, 980, (90, 90, 98))
img.save(out, "PNG", optimize=True)
print(f"OK: {out}")