A web app to help you design things, local, offline, on device. In your browser.
TypeScript
53.1%
JSON
45.6%
CSS
0.9%
Markdown
0.3%
JavaScript
0.1%
// AI Background Removal using @imgly/background-removal
// Runs entirely in-browser - no server needed
// License: AGPL (free for open source projects)
import { removeBackground, Config } from '@imgly/background-removal';
export interface BackgroundRemovalResult {
success: boolean;
blob?: Blob;
dataUrl?: string;
error?: string;
}
export interface BackgroundRemovalProgress {
progress: number;
stage: 'loading' | 'processing' | 'complete' | 'error';
message: string;
}
type ProgressCallback = (progress: BackgroundRemovalProgress) => void;
// Default configuration for background removal
const defaultConfig: Partial<Config> = {
// Use isnet_quint8 model for faster processing
model: 'isnet_quint8',
// Output format
output: {
format: 'image/png',
quality: 1,
},
};
/**
* Remove background from an image
* @param imageSource - Image source (URL, Blob, or File)
* @param onProgress - Progress callback
* @param config - Optional configuration overrides
*/
export async function removeImageBackground(
imageSource: string | Blob | File,
onProgress?: ProgressCallback,
config?: Partial<Config>
): Promise<BackgroundRemovalResult> {
try {
onProgress?.({
progress: 0,
stage: 'loading',
message: 'Loading AI model...',
});
const mergedConfig = {
...defaultConfig,
...config,
progress: (key: string, current: number, total: number) => {
const progress = Math.round((current / total) * 100);
onProgress?.({
progress,
stage: 'processing',
message: `Processing: ${progress}%`,
});
},
} as Config;
onProgress?.({
progress: 10,
stage: 'processing',
message: 'Analyzing image...',
});
const blob = await removeBackground(imageSource, mergedConfig);
onProgress?.({
progress: 100,
stage: 'complete',
message: 'Background removed!',
});
// Convert blob to data URL for immediate use
const dataUrl = await blobToDataUrl(blob);
return {
success: true,
blob,
dataUrl,
};
} catch (error) {
const errorMessage = error instanceof Error ? error.message : 'Unknown error occurred';
onProgress?.({
progress: 0,
stage: 'error',
message: errorMessage,
});
return {
success: false,
error: errorMessage,
};
}
}
/**
* Convert a Blob to a data URL
*/
function blobToDataUrl(blob: Blob): Promise<string> {
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.onloadend = () => resolve(reader.result as string);
reader.onerror = reject;
reader.readAsDataURL(blob);
});
}
/**
* Convert a data URL to a Blob
*/
export function dataUrlToBlob(dataUrl: string): Blob {
const arr = dataUrl.split(',');
const mime = arr[0].match(/:(.*?);/)?.[1] || 'image/png';
const bstr = atob(arr[1]);
let n = bstr.length;
const u8arr = new Uint8Array(n);
while (n--) {
u8arr[n] = bstr.charCodeAt(n);
}
return new Blob([u8arr], { type: mime });
}
/**
* Check if background removal is supported in this environment
*/
export function isBackgroundRemovalSupported(): boolean {
// Requires WebGL support
try {
const canvas = document.createElement('canvas');
const gl = canvas.getContext('webgl') || canvas.getContext('experimental-webgl');
return gl !== null;
} catch {
return false;
}
}
About
A web app to help you design things, local, offline, on device. In your browser.
0 stars
0 forks