DEV Community

monkeymore studio
monkeymore studio

Posted on

Building a Browser-Based AI Background Removal Tool

Introduction

In this article, we'll explore how to implement a powerful browser-based AI background removal tool that runs entirely in the browser. This tool uses the RMBG-1.4 deep learning model with WebGPU acceleration to remove backgrounds from images instantly, without sending any data to a server.

Why Browser-Based Background Removal?

1. Privacy Protection

When users remove backgrounds in the browser, their images never leave their device. This is essential for:

  • Personal photos requiring privacy
  • Business documents
  • Product images for e-commerce
  • Any content users want to keep confidential

2. Zero Server Costs

Running the AI model in the browser eliminates the need for:

  • GPU servers for deep learning inference
  • Bandwidth for uploading/downloading images
  • API costs for third-party background removal services

3. Instant Processing

No network round-trip means faster processing. Users see results immediately.

4. Offline Capability

Once the model is loaded, users can process images without an internet connection.

Technical Architecture

Core Implementation

1. Data Structures

interface ImageFile {
  id: string;
  file: File;
  previewUrl: string;
  resultUrl?: string;
  originalWidth: number;
  originalHeight: number;
}

interface RemoveBgClientProps {
  lang: Locale;
}

// Progress tracking state
interface ProgressState {
  phase: "downloading" | "building" | "ready";
  progress: number;
}
Enter fullscreen mode Exit fullscreen mode

2. Initializing rembg-webgpu

The tool uses rembg-webgpu, a WebGPU-powered implementation of the rembg model:

import { 
  removeBackground, 
  subscribeToProgress, 
  getCapabilities, 
  type ProgressState, 
  type RemoveBackgroundResult 
} from "rembg-webgpu";

const [capability, setCapability] = useState<string>("");
const [initialized, setInitialized] = useState(false);
const [loadingPhase, setLoadingPhase] = useState<string>("");

useEffect(() => {
  // Get device capabilities (WebGPU vs CPU)
  getCapabilities().then((cap) => {
    setCapability(`${cap.device} (${cap.dtype})`);
  });

  // Subscribe to model loading progress
  const unsubscribe = subscribeToProgress((state: ProgressState) => {
    const phase = state.phase;
    if (phase === "downloading") {
      setLoadingPhase("Downloading model...");
      setProgress(state.progress);
    } else if (phase === "building") {
      setLoadingPhase("Building model...");
      setProgress(state.progress);
    } else if (phase === "ready") {
      setLoadingPhase("Model loaded!");
      setProgress(100);
    }
  });

  // Initialize with a dummy image
  const init = async () => {
    try {
      await removeBackground("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg==");
      setInitialized(true);
    } catch (e) {
      console.error("Init error:", e);
    }
  };

  init();

  return () => {
    unsubscribe();
  };
}, []);
Enter fullscreen mode Exit fullscreen mode

3. Processing a Single Image

const processImage = useCallback(async (image: ImageFile) => {
  setProcessing(true);
  setProgress(0);

  try {
    // Call rembg-webgpu to remove background
    const result: RemoveBackgroundResult = await removeBackground(image.previewUrl);

    // Update state with result
    setImages((prev) =>
      prev.map((img) =>
        img.id === image.id ? { ...img, resultUrl: result.blobUrl } : img
      )
    );
  } catch (err) {
    console.error("Background removal error:", err);
  }

  setProcessing(false);
  setProgress(0);
}, []);
Enter fullscreen mode Exit fullscreen mode

4. Handling Multiple Images

const handleProcess = useCallback(async () => {
  if (!currentImage || currentImage.resultUrl || !initialized) return;
  await processImage(currentImage);
}, [currentImage, processImage, initialized]);

const handleProcessAll = useCallback(async () => {
  const imagesToProcess = images.filter((img) => !img.resultUrl);
  for (const img of imagesToProcess) {
    await processImage(img);
  }
}, [images, processImage]);
Enter fullscreen mode Exit fullscreen mode

5. Download Result

const handleDownload = (img: ImageFile) => {
  if (!img.resultUrl) return;
  const a = document.createElement("a");
  a.href = img.resultUrl;
  a.download = `removed_bg_${img.file.name.replace(/\.[^/.]+$/, "")}.png`;
  a.click();
};
Enter fullscreen mode Exit fullscreen mode

6. UI Display

The tool displays a checkerboard pattern behind transparent images:

<div className="aspect-video flex items-center justify-center bg-gray-200 dark:bg-gray-700 rounded-lg overflow-hidden relative">
  {currentImage.resultUrl ? (
    <img
      src={currentImage.resultUrl}
      alt="Result"
      className="max-w-full max-h-full object-contain"
      style={{ 
        backgroundImage: 'linear-gradient(45deg, #ccc 25%, transparent 25%), linear-gradient(-45deg, #ccc 25%, transparent 25%), linear-gradient(45deg, transparent 75%, #ccc 75%), linear-gradient(-45deg, transparent 75%, #ccc 75%)', 
        backgroundSize: '20px 20px', 
        backgroundPosition: '0 0, 0 10px, 10px -10px, -10px 0px' 
      }}
    />
  ) : (
    <div className="text-gray-400 text-center p-4">
      <ImageIcon className="w-8 h-8 mx-auto mb-2" />
      <p className="text-sm">Click process to remove background</p>
    </div>
  )}
</div>
Enter fullscreen mode Exit fullscreen mode

Service Worker for Model Caching

The ~100MB model is cached by a Service Worker for faster subsequent loads:

const CACHE_NAME = 'rembg-models-cache-v1';

const HF_CDN = 'https://cdn.jsdelivr.net/npm/@huggingface';

// Core ONNX Runtime Web files
const CORE_FILES = [
  `${HF_CDN}/transformers@2.1.0/examples_quantized/simd-webgpu/dist/ort-wasm-simd.wasm`,
  `${HF_CDN}/transformers@2.1.0/examples_quantized/simd-webgpu/dist/ort-wasm-simd-threaded.wasm`,
  `${HF_CDN}/transformers@2.1.0/examples_quantized/simd-webgpu/dist/ort-wasm-simd.fd`,
  `${HF_CDN}/transformers@2.1.0/examples_quantized/simd-webgpu/dist/ort-wasm-simd-threaded.fd`,
];

// RMBG 1.4 model
const MODEL_URLS = [
  'https://huggingface.co/briaai/RMBG-1.4/resolve/main/onnx/model.onnx',
];

self.addEventListener('fetch', (event) => {
  const url = new URL(event.request.url);

  // Cache ONNX Runtime WASM files
  if (url.pathname.includes('ort-wasm')) {
    event.respondWith(handleWasmRequest(event.request));
    return;
  }

  // Cache HuggingFace model files
  if (url.hostname.includes('huggingface')) {
    event.respondWith(handleModelRequest(event.request));
    return;
  }
});

async function handleWasmRequest(request) {
  const cachedResponse = await caches.match(request);
  if (cachedResponse) {
    return cachedResponse;
  }

  const networkResponse = await fetch(request);
  if (networkResponse.ok) {
    const cache = await caches.open(CACHE_NAME);
    cache.put(request, networkResponse.clone());
  }
  return networkResponse;
}
Enter fullscreen mode Exit fullscreen mode

Processing Flow

Key Technologies Used

Technology Purpose
rembg-webgpu Browser-based background removal
RMBG-1.4 Model BRIA AI's background removal model
ONNX Runtime Web Run ONNX models in browser
WebGPU GPU acceleration for inference
Service Worker Cache models for offline use

RMBG-1.4 Model

The tool uses RMBG-1.4 (Robust Background Matting) from BRIA AI:

  • Trained on diverse datasets
  • Works well on various image types
  • Produces clean alpha mattes
  • ~100MB model size

Device Capabilities

The tool detects and displays device capabilities:

getCapabilities().then((cap) => {
  setCapability(`${cap.device} (${cap.dtype})`);
});
Enter fullscreen mode Exit fullscreen mode

Possible outputs:

  • gpu (float16) - WebGPU with FP16
  • gpu (float32) - WebGPU with FP32
  • cpu (float32) - Fallback to CPU

Performance Characteristics

  1. Model Loading: 5-30 seconds (first time)
  2. Inference Time: 1-5 seconds per image (GPU)
  3. Memory Usage: ~500MB during processing
  4. Input Size: Up to 2048x2048 recommended
  5. Output: PNG with alpha channel (transparent background)

Browser Support

WebGPU requires modern browsers:

  • Chrome 113+
  • Edge 113+
  • Safari 17+ (limited support)
  • Firefox (WebGPU in development)

Use Cases

  1. Product Photography: Remove backgrounds from e-commerce photos
  2. Profile Pictures: Create transparent profile images
  3. Graphic Design: Extract subjects for compositions
  4. Document Processing: Remove backgrounds from scanned docs
  5. Social Media: Prepare images for posts

Comparison with Server-Based Solutions

Aspect Browser-Based Server-Based
Privacy 100% local Images leave device
Cost Free API costs
Speed Fast (GPU) Network dependent
Offline Yes (after cache) No
Quality Good May be better

Conclusion

Browser-based AI background removal brings professional-grade image processing to the web without privacy concerns. The implementation uses:

  • rembg-webgpu for WebGPU-accelerated background removal
  • RMBG-1.4 from BRIA AI as the segmentation model
  • ONNX Runtime Web for running the model in the browser
  • WebGPU for GPU-accelerated inference
  • Service Worker for model caching

Users can remove backgrounds from images instantly, all while their photos never leave their device.


Try it yourself at Free Image Tools

Experience the power of browser-based AI background removal. No upload required - your images stay on your device!

Top comments (0)