74 lines
2.3 KiB
JavaScript
74 lines
2.3 KiB
JavaScript
/**
|
|
* Suppression de fond par IA — @imgly/background-removal (WebAssembly).
|
|
* Le modèle (~40 Mo) est téléchargé depuis le CDN au premier lancement
|
|
* puis mis en cache automatiquement dans le navigateur.
|
|
*/
|
|
|
|
const CDN_VERSION = '1.7.0';
|
|
const CDN = `https://cdn.jsdelivr.net/npm/@imgly/background-removal@${CDN_VERSION}/dist/`;
|
|
|
|
// Chargement paresseux de la librairie (évite de bloquer le rendu initial)
|
|
let _removeBg = null;
|
|
|
|
async function loadLib() {
|
|
if (_removeBg) return _removeBg;
|
|
const mod = await import(CDN + 'index.mjs');
|
|
_removeBg = mod.removeBackground;
|
|
return _removeBg;
|
|
}
|
|
|
|
/**
|
|
* Supprime le fond d'un Blob image via IA.
|
|
* Retourne un nouveau Blob JPEG avec fond blanc pur.
|
|
* @param {Blob} blob — image source (JPEG)
|
|
* @param {function} [onProgress] — callback({ key, percent })
|
|
* @returns {Promise<Blob>} Blob JPEG fond blanc
|
|
*/
|
|
export async function removeBackground(blob, onProgress) {
|
|
const removeBg = await loadLib();
|
|
|
|
// Détourage IA → PNG avec transparence
|
|
const pngBlob = await removeBg(blob, {
|
|
// publicPath omis → utilise le CDN par défaut de img.ly (staticimgly.com)
|
|
output: {
|
|
format: 'image/png',
|
|
type: 'foreground',
|
|
quality: 1,
|
|
},
|
|
progress: (key, current, total) => {
|
|
if (onProgress && total > 0) {
|
|
onProgress({ key, percent: Math.round((current / total) * 100) });
|
|
}
|
|
},
|
|
});
|
|
|
|
// Composite sur fond blanc → JPEG
|
|
return compositeOnWhite(pngBlob);
|
|
}
|
|
|
|
/**
|
|
* Composite un PNG transparent sur fond blanc, retourne un Blob JPEG.
|
|
* @param {Blob} pngBlob
|
|
* @returns {Promise<Blob>}
|
|
*/
|
|
async function compositeOnWhite(pngBlob) {
|
|
return new Promise((resolve, reject) => {
|
|
const img = new Image();
|
|
img.onload = () => {
|
|
const canvas = document.createElement('canvas');
|
|
canvas.width = img.width;
|
|
canvas.height = img.height;
|
|
const ctx = canvas.getContext('2d');
|
|
ctx.fillStyle = '#ffffff';
|
|
ctx.fillRect(0, 0, canvas.width, canvas.height);
|
|
ctx.drawImage(img, 0, 0);
|
|
canvas.toBlob(b => {
|
|
URL.revokeObjectURL(img.src);
|
|
b ? resolve(b) : reject(new Error('canvas.toBlob a retourné null'));
|
|
}, 'image/jpeg', 0.92);
|
|
};
|
|
img.onerror = () => reject(new Error('Impossible de charger le résultat IA'));
|
|
img.src = URL.createObjectURL(pngBlob);
|
|
});
|
|
}
|