/** * Professional background removal using industry-standard libraries * This replaces the custom algorithm with proven solutions */ import { removeBackground as removeBackgroundLib } from '@imgly/background-removal'; // Type definitions for the background removal library interface BackgroundRemovalConfig { model?: 'small' | 'medium' | 'large'; output?: { format?: string; quality?: number; }; debug?: boolean; } /** * Remove background using AI-powered background removal * This is the preferred method for high-quality results */ export async function removeBackgroundAI(imageUrl: string): Promise { try { // Fetch the image as a blob const response = await fetch(imageUrl); if (!response.ok) { throw new Error(`Failed to fetch image: ${response.statusText}`); } const imageBlob = await response.blob(); // Remove background using AI (using default configuration for simplicity) const resultBlob = await removeBackgroundLib(imageBlob); // Convert result blob to data URL return new Promise((resolve, reject) => { const reader = new FileReader(); reader.onload = () => resolve(reader.result as string); reader.onerror = () => reject(new Error('Failed to convert result to data URL')); reader.readAsDataURL(resultBlob); }); } catch (error) { console.error('AI background removal failed:', error); throw new Error(`Background removal failed: ${error instanceof Error ? error.message : 'Unknown error'}`); } } /** * Simple fallback method for basic white background removal * Use this when the AI method is not available */ export async function removeWhiteBackgroundSimple(imageUrl: string): Promise { return new Promise((resolve, reject) => { const img = new Image(); img.crossOrigin = 'anonymous'; img.onload = () => { const canvas = document.createElement('canvas'); const ctx = canvas.getContext('2d'); if (!ctx) { reject(new Error('Failed to get canvas context')); return; } canvas.width = img.width; canvas.height = img.height; ctx.drawImage(img, 0, 0); const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height); const data = imageData.data; // Simple white background removal const whiteThreshold = 240; for (let i = 0; i < data.length; i += 4) { const r = data[i]; const g = data[i + 1]; const b = data[i + 2]; // If pixel is close to white, make it transparent if (r > whiteThreshold && g > whiteThreshold && b > whiteThreshold) { data[i + 3] = 0; // Set alpha to 0 } } ctx.putImageData(imageData, 0, 0); resolve(canvas.toDataURL('image/png')); }; img.onerror = () => { reject(new Error('Failed to load image')); }; img.src = imageUrl; }); } /** * Main function that tries AI method first, then falls back to simple method * This provides the best results while maintaining compatibility */ export async function removeBackground(imageUrl: string): Promise { try { // Try AI method first return await removeBackgroundAI(imageUrl); } catch (aiError) { console.warn('AI background removal failed, falling back to simple method:', aiError); try { // Fallback to simple method return await removeWhiteBackgroundSimple(imageUrl); } catch (fallbackError) { console.error('All background removal methods failed:', fallbackError); throw new Error('Background removal failed with all methods'); } } } /** * Check if the AI background removal library is available */ export async function isAIBackgroundRemovalAvailable(): Promise { return true; // Library is now installed as a dependency } /** * Batch process multiple images with progress callback */ export async function removeBackgroundBatch( imageUrls: string[], onProgress?: (completed: number, total: number, currentImage: string) => void ): Promise<{ url: string; result?: string; error?: string }[]> { const results: { url: string; result?: string; error?: string }[] = []; for (let i = 0; i < imageUrls.length; i++) { const imageUrl = imageUrls[i]; try { const result = await removeBackground(imageUrl); results.push({ url: imageUrl, result }); } catch (error) { const errorMessage = error instanceof Error ? error.message : 'Unknown error'; results.push({ url: imageUrl, error: errorMessage }); } if (onProgress) { onProgress(i + 1, imageUrls.length, imageUrl); } } return results; }