Files
feadulta/scripts/gen_avatars_initials.py

78 lines
2.7 KiB
Python

#!/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 «uid<TAB>display_name» (env FEA_TSV, por defecto /tmp/users29.tsv).
Salida: uploads/avatares/autores/autor-<uid>.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}")