#!/usr/bin/env python3 """Genera avatares de INICIALES (mismo formato que #62) para autores sin foto. Formato replicado del #62: PNG 200x200 RGBA, círculo de color sólido (paleta determinista de 10 tonos elegida por hash del nombre) con las iniciales en blanco, DejaVuSans-Bold, esquinas transparentes (borde circular supersampleado). Entrada: TSV «uiddisplay_name» (env FEA_TSV, por defecto /tmp/users29.tsv). Salida: uploads/avatares/autores/autor-.png Uso: FEA_TSV=/tmp/users29.tsv python3 scripts/gen_avatars_initials.py """ import hashlib, os, unicodedata from PIL import Image, ImageDraw, ImageFont OUT = "/home/rafa/joomla-migration/wordpress/wp-content/uploads/avatares/autores" TSV = os.environ.get("FEA_TSV", "/tmp/users29.tsv") FONT = "/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf" SIZE, SS = 200, 4 # Paleta del #62 (extraída de los avatares existentes; 10 tonos apagados) PALETTE = [ (91, 110, 80), (100, 110, 60), (160, 110, 70), (176, 122, 57), (150, 90, 110), (80, 80, 110), (74, 95, 120), (60, 90, 90), (139, 26, 46), (120, 82, 72), ] STOP = {"la", "las", "el", "los", "un", "una", "de", "del", "y", "e", "da", "do", "the"} def strip_accents(s: str) -> str: return "".join(c for c in unicodedata.normalize("NFD", s) if unicodedata.category(c) != "Mn") def initials(name: str) -> str: raw = name.replace("/", " ").replace('"', " ").replace("'", " ") toks = [t for t in raw.split() if t and t.lower() not in STOP] if not toks: return "?" picks = toks[:2] if len(toks) >= 2 else toks[:1] return strip_accents("".join(t[0] for t in picks)).upper() def color_for(name: str): h = int(hashlib.md5(name.encode("utf-8")).hexdigest(), 16) return PALETTE[h % len(PALETTE)] def make(uid: str, name: str): big = SIZE * SS im = Image.new("RGBA", (big, big), (0, 0, 0, 0)) d = ImageDraw.Draw(im) d.ellipse((0, 0, big - 1, big - 1), fill=color_for(name) + (255,)) txt = initials(name) # ajusta tamaño hasta cap-height ~77px (en escala SS) font = ImageFont.truetype(FONT, int(104 * SS)) bbox = d.textbbox((0, 0), txt, font=font) tw, th = bbox[2] - bbox[0], bbox[3] - bbox[1] x = (big - tw) / 2 - bbox[0] y = (big - th) / 2 - bbox[1] d.text((x, y), txt, font=font, fill=(255, 255, 255, 255)) im = im.resize((SIZE, SIZE), Image.LANCZOS) im.save(f"{OUT}/autor-{uid}.png") return txt os.makedirs(OUT, exist_ok=True) n = 0 for line in open(TSV, encoding="utf-8"): parts = line.rstrip("\n").split("\t") if len(parts) < 2: continue uid, name = parts[0].strip(), parts[1].strip() ini = make(uid, name) print(f"autor-{uid}.png {ini:3} {name}") n += 1 print(f"\n{n} avatares generados en {OUT}")