from PIL import Image, ImageDraw, ImageFont import os # warm palette matching the app BG_COLOR = (26, 23, 20) AMBER = (200, 149, 108) CREAM = (240, 236, 228) DARK_ACCENT = (60, 50, 40) def make_poster(title, key_sig, bpm, duration, out_path='poster.png'): """ generates a simple album-art-style card for the analyzed track. no ML here, just pillow. """ w, h = 800, 800 img = Image.new('RGB', (w, h), BG_COLOR) draw = ImageDraw.Draw(img) # big warm circle as a vinyl record silhouette cx, cy = w // 2, h // 2 - 40 radius = 240 draw.ellipse( [cx - radius, cy - radius, cx + radius, cy + radius], fill=DARK_ACCENT, outline=AMBER, width=3 ) # inner circle (label area) inner_r = 80 draw.ellipse( [cx - inner_r, cy - inner_r, cx + inner_r, cy + inner_r], fill=BG_COLOR, outline=AMBER, width=2 ) # spindle dot draw.ellipse([cx - 6, cy - 6, cx + 6, cy + 6], fill=AMBER) # grooves (concentric rings) for r in range(inner_r + 20, radius, 16): draw.ellipse( [cx - r, cy - r, cx + r, cy + r], outline=(50, 42, 34), width=1 ) # text below the record try: title_font = ImageFont.truetype("/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf", 32) detail_font = ImageFont.truetype("/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf", 22) small_font = ImageFont.truetype("/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf", 16) except OSError: title_font = ImageFont.load_default() detail_font = title_font small_font = title_font # track title title_text = title if len(title) < 40 else title[:37] + '...' bbox = draw.textbbox((0, 0), title_text, font=title_font) tw = bbox[2] - bbox[0] draw.text(((w - tw) // 2, h - 200), title_text, fill=CREAM, font=title_font) # key + bpm line info_text = f"{key_sig} · {bpm} BPM · {duration:.1f}s" bbox = draw.textbbox((0, 0), info_text, font=detail_font) tw = bbox[2] - bbox[0] draw.text(((w - tw) // 2, h - 150), info_text, fill=AMBER, font=detail_font) # coda branding brand = "CODA" bbox = draw.textbbox((0, 0), brand, font=small_font) tw = bbox[2] - bbox[0] draw.text(((w - tw) // 2, h - 60), brand, fill=(100, 85, 70), font=small_font) img.save(out_path) return out_path