dragoman / make_thumbnail.py
ciscoriordan's picture
make_thumbnail: take source/output paths as CLI args
d99cc14
Raw
History Blame Contribute Delete
2.32 kB
#!/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}")