#!/usr/bin/env python3 """Build the Dragoman 1200x630 social / HF thumbnail. Usage: make_thumbnail.py SOURCE_IMAGE [-o OUTPUT] """ import argparse from pathlib import Path import numpy as np from PIL import Image, ImageDraw, ImageFont parser = argparse.ArgumentParser(description=__doc__) parser.add_argument("source", help="source artwork image") parser.add_argument("-o", "--output", default=Path(__file__).parent / "thumbnail.png", help="output path (default: thumbnail.png next to this script)") args = parser.parse_args() SRC = args.source OUT = args.output W, H = 1200, 630 img = Image.open(SRC).convert("RGB") scale = W / img.width new_h = int(img.height * scale) img = img.resize((W, new_h), Image.LANCZOS) crop_y = 170 img = img.crop((0, crop_y, W, crop_y + H)) ys, xs = np.mgrid[0:H, 0:W].astype(np.float32) cx, cy = W - 40, 20 dist = np.sqrt((xs - cx) ** 2 + (ys - cy) ** 2) inner, outer = 120.0, 780.0 t = np.clip((dist - inner) / (outer - inner), 0.0, 1.0) falloff = (1.0 - t) ** 1.4 alpha = (falloff * 215).astype(np.uint8) scrim_rgba = np.zeros((H, W, 4), dtype=np.uint8) scrim_rgba[..., 3] = alpha scrim = Image.fromarray(scrim_rgba, "RGBA") base = img.convert("RGBA") base = Image.alpha_composite(base, scrim) font_path = "/System/Library/Fonts/Supplemental/Baskerville.ttc" title_font = ImageFont.truetype(font_path, 64, index=1) # SemiBold subtitle_font = ImageFont.truetype(font_path, 30, index=0) # Regular draw = ImageDraw.Draw(base) text = "DRAGOMAN" tracking = 9 widths = [] for ch in text: bbox = title_font.getbbox(ch) widths.append(bbox[2] - bbox[0]) total_w = sum(widths) + tracking * (len(text) - 1) ascent, _ = title_font.getmetrics() right_margin = 54 top_margin = 58 x = W - right_margin - total_w y = top_margin cursor = x for i, ch in enumerate(text): bbox = title_font.getbbox(ch) draw.text((cursor - bbox[0], y), ch, font=title_font, fill=(246, 240, 230, 255)) cursor += widths[i] + tracking subtitle = "Diachronic Greek Word Alignment" sub_bbox = subtitle_font.getbbox(subtitle) sub_w = sub_bbox[2] - sub_bbox[0] sub_x = W - right_margin - sub_w sub_y = y + ascent + 10 draw.text((sub_x, sub_y), subtitle, font=subtitle_font, fill=(230, 220, 205, 240)) base.convert("RGB").save(OUT, "PNG", optimize=True) print(f"wrote {OUT}")