Skip to content

Remove Background: cut out or change a photo's background, on the device - #90

Merged
kingrishabdugar merged 3 commits into
mainfrom
feat/remove-background
Oct 8, 2026
Merged

kingrishabdugar merged 3 commits into
mainfrom
feat/remove-background

Conversation

@kingrishabdugar

@kingrishabdugar kingrishabdugar commented Oct 8, 2026 •

Copy link
Copy Markdown
Owner

New tool at /remove-background/.

For the person using it

  • Choose a photo; the background is removed straight away, no button to find.
  • Pick what goes behind: none (transparent PNG), white, black, blue, red, green, grey, any colour, your own photo, or a blur of the original.
  • Size: original resolution (no cap from us), a few common widths, or a custom width.
  • Touch up: Erase / Restore brush with Undo; the picture scrolls into view when the brush is picked.
  • "Hold to see the original" to compare.
  • Big, labelled buttons; works on phones (390 px checked, no sideways scroll).

How it works

  • BiRefNet-lite (MIT) in a worker with ONNX Runtime Web: WebGPU when the device has a usable GPU, the CPU build otherwise. It runs at 512 px; the 1024 px export needs about 7 GB of memory, which browsers can't give.
  • Weights stored as 16-bit floats and cast back on load (scripts/background-model.py): 103 MB download instead of 192 MB, and the CPU build can still run it. Downloaded once into Cache Storage.
  • Fallbacks: GPU fails → same model on CPU → U²-Net small (Apache-2.0, 4.6 MB). Phones reporting < 4 GB start with U²-Net small and say so.
  • Full-size result: the mask is fitted to the photo with a fast colour guided filter (contrast firmed first; tuned on portraits so fly-away hair survives) and edge colours are cleaned with blur-fusion foreground estimation, so no halo of the old background. Everything heavy happens at ≤ 1280 px and is applied to the full image in one pass, so memory stays small.
  • Model parts and the WebGPU runtime (/bg/ort/, split under 25 MiB) are served from our own origin; CSP unchanged. .gitattributes marks model files binary.

Checks

  • Unit tests for the box filter, guided filter, foreground colours and the full refine step.
  • e2e runs the real model on CPU: transparent corners, opaque subject at exactly the original pixels, white JPG at a smaller size, erase + undo, no CSP violations, no requests off-site.
  • Full suite: 214 unit tests, 1108 e2e tests passing locally.
  • Not covered by CI: a real GPU. It loads and runs on a software GPU here, and any GPU failure falls back to the CPU.

Strings in all 16 languages; credits added to README, THIRD_PARTY_NOTICES.md and third-party-licenses.txt. Tool count 64 → 65.

New Remove Background tool. The background goes as soon as a photo is
chosen; then pick what goes behind it (nothing, white, a colour, your own
photo or a blur), the size, and touch up any spot with Erase / Restore.

- BiRefNet-lite (MIT) runs in a worker with ONNX Runtime Web: on the GPU
  through WebGPU where available, on the CPU otherwise. It sees the photo
  at 512 px, which keeps it within browser memory (the 1024 px export
  needs ~7 GB). Weights are stored as 16-bit floats (103 MB download,
  cached once) and cast back on load, so the CPU build can run it too.
- Phones that report little memory, or where the big model fails, use
  U2-Net small (Apache-2.0, 4.6 MB). A GPU that fails falls back to the
  same model on the CPU first.
- The mask is fitted to the full-size photo with a fast colour guided
  filter, and edge colours are cleaned with blur-fusion foreground
  estimation, so hair keeps its strands and no halo of the old background
  shows. Output keeps the photo's own resolution; smaller sizes or a
  custom width are one click away.
- Model files and the WebGPU runtime are served in parts from our own
  origin, like the speech model; the CSP is unchanged.
- Strings in all 16 languages, credits in README and the licence files,
  unit tests for the filters and an e2e test that runs the real model.
@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Oct 8, 2026 •

Copy link
Copy Markdown

Deploying fizzdoc with  Cloudflare Pages  Cloudflare Pages

Latest commit: c9a7e26
Status: ✅  Deploy successful!
Preview URL: https://e13a3d64.fizzdoc.pages.dev
Branch Preview URL: https://feat-remove-background.fizzdoc.pages.dev

View logs

The bundled WebGPU build points at its 27 MB binary with new URL(), so
Vite copied it into dist/assets, and Cloudflare Pages refuses files over
25 MiB. The extern-wasm build loads its small loader from /bg/ort/ and
gets the binary from the parts we already serve.
Cloudflare Pages refuses such files at deploy time; this catches them in
the build and in CI, with a hint to split the file into parts.
@kingrishabdugar
kingrishabdugar merged commit 27a62bb into main Oct 8, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant