Mode fond vert : choix du fond apres la photo

- Apres la capture, si chroma key active, une barre de fonds
  s'affiche avec des miniatures cliquables
- L'utilisateur choisit son fond parmi la liste
- Remplacement du fond vert en temps reel (OpenCV backend)
- Onglet "Fonds verts" dans le backoffice pour importer/supprimer
  des images de fond
- Miniatures visuelles dans l'admin et sur l'ecran de preview

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-03-21 23:45:45 +01:00
parent c10812b4c0
commit 32392d3ccd
6 changed files with 221 additions and 4 deletions

View File

@@ -1,7 +1,8 @@
/* Module effets - Filtres et overlays */
/* Module effets - Filtres, overlays et fond vert */
let filtreActuel = 'original';
let overlayActuel = null;
let fondActuel = null;
async function chargerFiltres() {
const filtres = await apiGet('/api/filtres');
@@ -18,7 +19,6 @@ async function chargerFiltres() {
}
async function appliquerFiltreUI(filtre, btn) {
// Activer visuellement
document.querySelectorAll('.btn-filtre').forEach(b => b.classList.remove('actif'));
btn.classList.add('actif');
filtreActuel = filtre;
@@ -55,7 +55,6 @@ async function chargerOverlays() {
barre.classList.remove('cache');
barre.innerHTML = '';
// Bouton "sans overlay"
const btnAucun = document.createElement('button');
btnAucun.className = 'btn-overlay actif';
btnAucun.textContent = 'Sans cadre';
@@ -91,7 +90,71 @@ function retirerOverlay(btn) {
btn.classList.add('actif');
overlayActuel = null;
// Revenir a la photo avec filtre actuel (ou originale)
if (filtreActuel !== 'original') {
appliquerFiltreUI(filtreActuel, document.querySelector('.btn-filtre.actif'));
} else {
const chemin = '/data/photos/' + photosSession[0];
document.getElementById('photo-resultat').src = chemin;
document.getElementById('photo-partage').src = chemin;
photoFinale = photosSession[0];
}
}
// === Fond vert (chroma key) ===
async function chargerFonds() {
const fonds = await apiGet('/api/fonds');
const barre = document.getElementById('barre-fonds');
if (!config.fonctionnalites?.chroma_key || fonds.length === 0) {
barre.classList.add('cache');
return;
}
barre.classList.remove('cache');
barre.innerHTML = '';
fondActuel = null;
// Bouton "original" (pas de chroma key)
const btnOriginal = document.createElement('button');
btnOriginal.className = 'btn-fond actif';
btnOriginal.innerHTML = '<span style="font-size:0.7rem;color:var(--texte-secondaire)">Original</span>';
btnOriginal.addEventListener('click', () => retirerFond(btnOriginal));
barre.appendChild(btnOriginal);
for (const nom of fonds) {
const btn = document.createElement('button');
btn.className = 'btn-fond';
const img = document.createElement('img');
img.src = `/assets/backgrounds/${nom}`;
img.alt = nom;
btn.appendChild(img);
btn.addEventListener('click', () => appliquerFondUI(nom, btn));
barre.appendChild(btn);
}
}
async function appliquerFondUI(nom, btn) {
document.querySelectorAll('.btn-fond').forEach(b => b.classList.remove('actif'));
btn.classList.add('actif');
fondActuel = nom;
const photo = photosSession[0];
const resultat = await apiPost('/api/chroma', { photo, fond: nom });
if (resultat.nom) {
photoFinale = resultat.nom;
document.getElementById('photo-resultat').src = '/data/exports/' + resultat.nom;
document.getElementById('photo-partage').src = '/data/exports/' + resultat.nom;
}
}
function retirerFond(btn) {
document.querySelectorAll('.btn-fond').forEach(b => b.classList.remove('actif'));
btn.classList.add('actif');
fondActuel = null;
// Revenir a la photo originale ou avec filtre
if (filtreActuel !== 'original') {
appliquerFiltreUI(filtreActuel, document.querySelector('.btn-filtre.actif'));
} else {