78 lines
2.7 KiB
Python
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}")
|