Cadres impression : fallback cross-format (15x20 utilise le 10x15 si pas de cadre dédié)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-09-24 13:29:13 +02:00
parent 61b9a72f10
commit 2f32cf2f38

View File

@@ -121,18 +121,32 @@ def chroma_key(chemin_photo: Path, nom_fond: str | None = None,
return chemin_export return chemin_export
def appliquer_cadre_impression(img: Image.Image, format_papier: str, nom_cadre: str, event_id: str | None = None) -> Image.Image: def _chercher_cadre(format_papier: str, nom_cadre: str, event_id: str | None = None) -> Path | None:
"""Composite un cadre PNG par-dessus l'image assemblée.""" """Cherche le cadre dans le format demandé, sinon fallback autres formats."""
chemin = None candidats = []
if event_id: if event_id:
from backend.evenements import DOSSIER_EVENEMENTS from backend.evenements import DOSSIER_EVENEMENTS
chemin_event = DOSSIER_EVENEMENTS / event_id / "cadres" / format_papier / nom_cadre base_event = DOSSIER_EVENEMENTS / event_id / "cadres"
if chemin_event.exists(): candidats.append(base_event / format_papier / nom_cadre)
chemin = chemin_event for d in sorted(base_event.iterdir()) if base_event.exists() else []:
if d.is_dir() and d.name != format_papier:
candidats.append(d / nom_cadre)
candidats.append(DOSSIER_CADRES / format_papier / nom_cadre)
for d in sorted(DOSSIER_CADRES.iterdir()) if DOSSIER_CADRES.exists() else []:
if d.is_dir() and d.name != format_papier:
candidats.append(d / nom_cadre)
for c in candidats:
if c.exists():
return c
return None
def appliquer_cadre_impression(img: Image.Image, format_papier: str, nom_cadre: str, event_id: str | None = None) -> Image.Image:
"""Composite un cadre PNG par-dessus l'image assemblée.
Si le cadre n'existe pas dans le format demandé, utilise celui d'un autre format (resize)."""
chemin = _chercher_cadre(format_papier, nom_cadre, event_id)
if chemin is None: if chemin is None:
chemin = DOSSIER_CADRES / format_papier / nom_cadre log.warning(f"Cadre introuvable : {nom_cadre} pour {format_papier}")
if not chemin.exists():
log.warning(f"Cadre introuvable : {chemin}")
return img return img
cadre = Image.open(chemin).convert("RGBA") cadre = Image.open(chemin).convert("RGBA")
img_portrait = img.height > img.width img_portrait = img.height > img.width
@@ -147,11 +161,16 @@ def appliquer_cadre_impression(img: Image.Image, format_papier: str, nom_cadre:
def lister_cadres(format_papier: str) -> list[str]: def lister_cadres(format_papier: str) -> list[str]:
"""Liste les cadres disponibles pour un format donné.""" """Liste les cadres disponibles pour un format. Inclut ceux d'autres formats en fallback."""
noms = set()
dossier = DOSSIER_CADRES / format_papier dossier = DOSSIER_CADRES / format_papier
if not dossier.exists(): if dossier.exists():
return [] noms.update(f.name for f in dossier.iterdir() if f.suffix.lower() == ".png")
return sorted(f.name for f in dossier.iterdir() if f.suffix.lower() == ".png") if not noms and DOSSIER_CADRES.exists():
for d in DOSSIER_CADRES.iterdir():
if d.is_dir():
noms.update(f.name for f in d.iterdir() if f.suffix.lower() == ".png")
return sorted(noms)
def lister_overlays() -> list[str]: def lister_overlays() -> list[str]: