"""Render a courtroom-sketch witness placard as the portrait placeholder. python3 scripts/make_portrait_placeholder.py -> assets/marcus_reid.png app.py shows assets/marcus_reid.png if it exists, else an empty box. A real AI portrait (HF ZeroGPU) can overwrite this file later; until then this gives the demo an intentional, on-theme visual instead of a blank frame. Pure PIL โ€” no GPU, no network โ€” and it matches the app's parchment palette. """ from __future__ import annotations import os from PIL import Image, ImageDraw, ImageFont W, H = 768, 960 PARCH = (239, 231, 211) # #efe7d3 page CARD = (247, 241, 225) # #f7f1e1 BORDER = (201, 183, 141) # #c9b78d INK = (58, 44, 24) # #3a2c18 SUB = (107, 88, 54) # #6b5836 MAROON = (122, 47, 47) # #7a2f2f SKETCH = (90, 74, 53) # sepia for the silhouette SKETCH_HI = (120, 102, 78) FONT_DIRS = [ "/System/Library/Fonts/Supplemental/", "/System/Library/Fonts/", "/Library/Fonts/", ] SERIF = ["Georgia.ttf", "Palatino.ttc", "Times New Roman.ttf", "Baskerville.ttc"] SERIF_B = ["Georgia Bold.ttf", "Times New Roman Bold.ttf", "Georgia.ttf"] def _font(names, size): for d in FONT_DIRS: for n in names: p = os.path.join(d, n) if os.path.exists(p): try: return ImageFont.truetype(p, size) except Exception: pass return ImageFont.load_default() def _spaced(draw, xy, text, font, fill, spacing=6, anchor_center=None): """Draw letter-spaced text; if anchor_center given, center on that x.""" widths = [draw.textlength(c, font=font) for c in text] total = sum(widths) + spacing * (len(text) - 1) x = (anchor_center - total / 2) if anchor_center is not None else xy[0] y = xy[1] for c, w in zip(text, widths): draw.text((x, y), c, font=font, fill=fill) x += w + spacing return total def _scales(draw, cx, top): """A small balance-scale glyph, drawn from primitives.""" col = INK draw.line([(cx, top), (cx, top + 54)], fill=col, width=4) # post draw.ellipse([cx - 5, top - 5, cx + 5, top + 5], fill=col) # finial beam_y, span = top + 14, 70 draw.line([(cx - span, beam_y), (cx + span, beam_y)], fill=col, width=4) for sx in (cx - span, cx + span): draw.line([(sx, beam_y), (sx - 18, beam_y + 34)], fill=col, width=2) draw.line([(sx, beam_y), (sx + 18, beam_y + 34)], fill=col, width=2) draw.arc([sx - 20, beam_y + 24, sx + 20, beam_y + 50], 0, 180, fill=col, width=3) draw.line([(cx - 26, top + 54), (cx + 26, top + 54)], fill=col, width=4) # base def _silhouette(draw, cx, cy): """A courtroom-sketch bust: shoulders, neck, head, with a suit + tie hint.""" # shoulders / suit draw.ellipse([cx - 165, cy + 70, cx + 165, cy + 360], fill=SKETCH) draw.rectangle([cx - 165, cy + 215, cx + 165, cy + 360], fill=SKETCH) # collar V + tie draw.polygon([(cx - 40, cy + 95), (cx, cy + 185), (cx + 40, cy + 95)], fill=CARD) draw.polygon([(cx - 12, cy + 120), (cx + 12, cy + 120), (cx + 18, cy + 210), (cx, cy + 235), (cx - 18, cy + 210)], fill=(64, 40, 40)) # tie draw.polygon([(cx - 40, cy + 95), (cx - 14, cy + 112), (cx, cy + 150), (cx - 16, cy + 150)], fill=SKETCH_HI) # lapel L draw.polygon([(cx + 40, cy + 95), (cx + 14, cy + 112), (cx, cy + 150), (cx + 16, cy + 150)], fill=SKETCH_HI) # lapel R # neck + head draw.rectangle([cx - 26, cy + 40, cx + 26, cy + 110], fill=SKETCH) draw.ellipse([cx - 70, cy - 110, cx + 70, cy + 60], fill=SKETCH) # hair sweep draw.chord([cx - 72, cy - 120, cx + 72, cy + 10], 180, 360, fill=SKETCH_HI) def main(): root = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) out_dir = os.path.join(root, "assets") os.makedirs(out_dir, exist_ok=True) out = os.path.join(out_dir, "marcus_reid.png") img = Image.new("RGB", (W, H), PARCH) d = ImageDraw.Draw(img) # card with double frame m = 28 d.rectangle([m, m, W - m, H - m], fill=CARD, outline=BORDER, width=3) d.rectangle([m + 12, m + 12, W - m - 12, H - m - 12], outline=BORDER, width=1) f_top = _font(SERIF_B, 30) f_name = _font(SERIF_B, 58) f_sub = _font(SERIF, 27) f_foot = _font(SERIF, 20) _scales(d, W // 2, 62) _spaced(d, (0, 150), "SWORN WITNESS", f_top, MAROON, spacing=10, anchor_center=W // 2) _silhouette(d, W // 2, 330) # nameplate bar bar_y = 720 d.rectangle([m + 40, bar_y, W - m - 40, bar_y + 86], fill=INK) _spaced(d, (0, bar_y + 16), "MARCUS REID", f_name, CARD, spacing=4, anchor_center=W // 2) sub = "Chief Financial Officer ยท Halcyon Dynamics" tw = d.textlength(sub, font=f_sub) d.text(((W - tw) / 2, bar_y + 104), sub, font=f_sub, fill=SUB) foot = "WitnessBox โ€” State's Exhibit" fw = d.textlength(foot, font=f_foot) d.text(((W - fw) / 2, H - m - 52), foot, font=f_foot, fill=BORDER) img.save(out) print(f"wrote {out} ({W}x{H})") if __name__ == "__main__": main()