From 2f32cf2f382800c7142bb94d08a388cc78ca796a Mon Sep 17 00:00:00 2001 From: Jules Date: Thu, 24 Sep 2026 13:29:13 +0200 Subject: [PATCH] =?UTF-8?q?Cadres=20impression=20:=20fallback=20cross-form?= =?UTF-8?q?at=20(15x20=20utilise=20le=2010x15=20si=20pas=20de=20cadre=20d?= =?UTF-8?q?=C3=A9di=C3=A9)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 4.6 --- backend/effects.py | 45 ++++++++++++++++++++++++++++++++------------- 1 file changed, 32 insertions(+), 13 deletions(-) diff --git a/backend/effects.py b/backend/effects.py index b230ae1..d2ddb0e 100644 --- a/backend/effects.py +++ b/backend/effects.py @@ -121,18 +121,32 @@ def chroma_key(chemin_photo: Path, nom_fond: str | None = None, return chemin_export -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.""" - chemin = None +def _chercher_cadre(format_papier: str, nom_cadre: str, event_id: str | None = None) -> Path | None: + """Cherche le cadre dans le format demandé, sinon fallback autres formats.""" + candidats = [] if event_id: from backend.evenements import DOSSIER_EVENEMENTS - chemin_event = DOSSIER_EVENEMENTS / event_id / "cadres" / format_papier / nom_cadre - if chemin_event.exists(): - chemin = chemin_event + base_event = DOSSIER_EVENEMENTS / event_id / "cadres" + candidats.append(base_event / format_papier / nom_cadre) + 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: - chemin = DOSSIER_CADRES / format_papier / nom_cadre - if not chemin.exists(): - log.warning(f"Cadre introuvable : {chemin}") + log.warning(f"Cadre introuvable : {nom_cadre} pour {format_papier}") return img cadre = Image.open(chemin).convert("RGBA") 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]: - """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 - if not dossier.exists(): - return [] - return sorted(f.name for f in dossier.iterdir() if f.suffix.lower() == ".png") + if dossier.exists(): + noms.update(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]: