"""Genereer de social-share-afbeelding (OG-image) 1200x630 voor Helvoirt Gevelreiniging. Neemt een echte werkfoto (schone gevel), crop-cover naar 1200x630, legt er een petrol-gradient over (links/onder donker voor leesbaarheid) en zet de wordmark + tagline + 4,9-Google-regel eroverheen. Output: public/images/og-default.webp. Draaien (Windows): $py = "C:\\Users\\info\\AppData\\Local\\Programs\\Python\\Python312\\python.exe" & $py scripts/make-og.py """ from PIL import Image, ImageDraw, ImageFont import os W, H = 1200, 630 SRC = os.path.join("public", "images", "hero-after.webp") OUT = os.path.join("public", "images", "og-default.webp") # Merkkleuren (uit tokens.css) PETROL_DEEP = (21, 54, 61) # #15363d CYAAN = (78, 191, 217) # #4ebfd9 STAR = (255, 196, 0) WHITE = (255, 255, 255) SOFT = (199, 218, 224) # #c7dae0 (on-dark-soft) FONTS = "C:/Windows/Fonts" def load(name, size): return ImageFont.truetype(os.path.join(FONTS, name), size) def cover(im, w, h): """Schaal + crop zodat de foto het hele vlak vult (object-fit: cover).""" src_ratio = im.width / im.height dst_ratio = w / h if src_ratio > dst_ratio: new_h = h new_w = round(h * src_ratio) else: new_w = w new_h = round(w / src_ratio) im = im.resize((new_w, new_h), Image.LANCZOS) left = (new_w - w) // 2 top = (new_h - h) // 2 return im.crop((left, top, left + w, top + h)) def main(): base = cover(Image.open(SRC).convert("RGB"), W, H) # Petrol-gradient: links sterk donker -> rechts transparant (tekst leesbaar links). overlay = Image.new("RGBA", (W, H), (0, 0, 0, 0)) od = overlay.load() for x in range(W): # alpha van ~0.92 links naar ~0.05 rechts t = x / W a = int(235 * (1 - t) ** 1.5 + 12) for y in range(H): od[x, y] = (*PETROL_DEEP, a) # extra donkere voet onderaan voor de tagline foot = Image.new("RGBA", (W, H), (0, 0, 0, 0)) fd = foot.load() for y in range(H): t = max(0, (y - H * 0.55) / (H * 0.45)) a = int(160 * t) for x in range(W): fd[x, y] = (*PETROL_DEEP, a) img = Image.alpha_composite(base.convert("RGBA"), overlay) img = Image.alpha_composite(img, foot) draw = ImageDraw.Draw(img) # Cyaan accent-balk links draw.rectangle([0, 0, 12, H], fill=CYAAN) pad = 70 # Wordmark (twee regels, zwaar) f_brand = load("ariblk.ttf", 86) f_sub = load("ariblk.ttf", 86) draw.text((pad, 150), "Helvoirt", font=f_brand, fill=WHITE) draw.text((pad, 248), "Gevelreiniging", font=f_sub, fill=CYAAN) # Tagline f_tag = load("segoeui.ttf", 34) draw.text((pad, 372), "Gevelreiniging · voegwerk · dakreiniging + coating", font=f_tag, fill=SOFT) # 4,9 op Google (sterren + tekst). Sterren via Segoe UI Symbol (heeft U+2605). f_score = load("arialbd.ttf", 40) f_stars = load("seguisym.ttf", 34) y_score = 452 draw.text((pad, y_score), "★★★★★", font=f_stars, fill=STAR) stars_w = draw.textlength("★★★★★", font=f_stars) draw.text((pad + stars_w + 20, y_score - 3), "4,9 op Google", font=f_score, fill=WHITE) # Werkgebied-regel f_region = load("segoeui.ttf", 28) draw.text((pad, 520), "Helvoirt en omgeving", font=f_region, fill=SOFT) img.convert("RGB").save(OUT, "WEBP", quality=88, method=6) print("OG-image geschreven:", OUT, Image.open(OUT).size) if __name__ == "__main__": main()