/** * Lecture d'un ZIP produits. * Attend une structure : dossier-produit/image.heic (ou jpg/png). * JSZip est chargé comme script global dans index.html. */ const IMAGE_EXTS = new Set(['heic', 'heif', 'jpg', 'jpeg', 'png']); /** * Extrait toutes les images d'un fichier ZIP. * @param {File} zipFile * @returns {Promise>} */ export async function readImagesFromZip(zipFile) { const zip = await JSZip.loadAsync(zipFile); // Collecter les entrées fichier (pas les dossiers) const entries = []; zip.forEach((relativePath, entry) => { if (!entry.dir) entries.push({ relativePath, entry }); }); const results = []; for (const { relativePath, entry } of entries) { // Ignorer les métadonnées macOS et fichiers cachés if (relativePath.startsWith('__MACOSX/')) continue; const parts = relativePath.split('/').filter(p => p.length > 0); const filename = parts[parts.length - 1]; if (filename.startsWith('.')) continue; // Extension const dotIdx = filename.lastIndexOf('.'); if (dotIdx === -1) continue; const ext = filename.slice(dotIdx + 1).toLowerCase(); if (!IMAGE_EXTS.has(ext)) continue; const name = filename.slice(0, dotIdx); // Premier segment du chemin = dossier produit (ex: "12345") const folder = parts.length > 1 ? parts[0] : ''; const isHeic = ext === 'heic' || ext === 'heif'; const mimeType = isHeic ? 'image/heic' : (ext === 'jpg' || ext === 'jpeg') ? 'image/jpeg' : 'image/png'; // JSZip retourne des Blobs sans type MIME — on le définit explicitement // pour que heic2any puisse détecter le format correctement. const rawBlob = await entry.async('blob'); const blob = new Blob([rawBlob], { type: mimeType }); results.push({ folder, name, ext, blob, isHeic }); } return results; }