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;
} |