File size: 5,237 Bytes
edc4c90
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
/**
 * 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<string> {
    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<string> {
    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<string> {
    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<boolean> {
    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;
}