# Background Remover for Images (rembg, CPU) (`data-done-right/background-remover`) Actor

Remove the background from images in bulk: image URLs in, transparent PNG or WebP out with download links. Optional solid colour background and crop to subject. CPU only, no API key. Direct image files only; softer on hair and fine edges than GPU models.

- **URL**: https://apify.com/data-done-right/background-remover.md
- **Developed by:** [Data Done Right](https://apify.com/data-done-right) (community)
- **Categories:** Developer tools, Automation, AI
- **Security:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $6.40 / 1,000 image processeds

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Background Remover for Images (rembg, CPU)

This **background remover** takes a list of direct image URLs, removes the background from each image with the open-source **rembg** library and the **U2-Net** model, and gives you a download link for every result as a **transparent PNG or WebP**, optionally on a solid colour and cropped to the subject. It runs on CPU in the cloud: no GPU, no API key, nothing to install.

> **What it does not do.** It reads **direct image files** (JPEG, PNG, WebP, BMP, GIF, TIFF) from a public URL. It does not open web pages, social media posts, HEIC photos (convert them first), SVG or video. It is **not a BiRefNet or GPU-grade matting tool**: U2-Net on CPU is softer on **hair, fur, glass and fine edges**, and it can cut incompletely when a dark subject stands against a bright background (see "Quality and limits" below). There is no alpha matting, no manual brush and no background replacement with another picture, only transparent or one flat colour. Use it on images you own or have the right to edit.

**What you get**

- One dataset row per image: your source URL, a signed download link to the cut-out, width and height, file size, the share of the image detected as subject (`foregroundPercent`), the time it took, and a clear error if it failed.
- Transparent PNG (lossless) or WebP (smaller), or a flat background colour such as `#ffffff`, and an optional crop to the subject.
- Failed, rejected and "no subject found" images are free; one bad link never stops the run.

### How to remove the background from an image URL

1. Paste one or more **direct image URLs** in `imageUrls`, for example `https://example.com/product.jpg`.
2. Leave the defaults (model `u2net`, PNG, transparent background) and run.
3. Open the dataset: the `url` column links to each cut-out. The files are also in the run's key-value store.

### How to put a white background behind product photos

Set `"backgroundColor": "#ffffff"` (any hex colour works: `#f4f4f4`, `#000`) and, for tight shop images, `"cropToSubject": true`. The result is an opaque image with the subject on that colour. WebP output keeps files small.

### How to make a transparent PNG and crop it to the subject

Keep `"backgroundColor": "transparent"` and set `"cropToSubject": true`. The empty margin is trimmed to the bounding box of the detected subject. `width` and `height` in the row are the size of the final file.

### How to remove backgrounds from many images quickly

Switch `model` to `u2netp`: about twice as fast, fine for **single objects on plain backgrounds**, but in our tests it lost the arms on a photo of a person and failed on a silhouette. Raise `maxImagesPerRun` (default 100, up to 2000). Duplicate URLs are processed once.

### Input

| Field | Default | What it does |
|---|---|---|
| `imageUrls` | one sample photo | Direct image links (strings, or objects with a `url`). Required. |
| `model` | `u2net` | `u2net` (better on people and thin parts) or `u2netp` (about 2x faster, simple objects). |
| `outputFormat` | `png` | `png` (lossless) or `webp` (quality 90, smaller). Both keep transparency. |
| `backgroundColor` | `transparent` | `transparent` or a hex colour like `#ffffff`. |
| `cropToSubject` | `false` | Trim the result to the detected subject. |
| `maxImagesPerRun` | 100 | Hard cap per run (max 2000). Extra images are listed as skipped, free. |
| `maxImageSizeMb` | 25 | Larger downloads are rejected (max 100). |
| `maxMegapixels` | 40 | Larger images are rejected before decoding (max 50). |
| `maxLongSide` | 4096 | Larger images are downscaled first; the row's `note` says so. |
| `imageTimeoutSecs` | 120 | Download plus processing time per image. |
| `outputStoreName` | empty | Keep the result files in a named store until you delete it. |

Input example:

```json
{
  "imageUrls": ["https://interactive-examples.mdn.mozilla.net/media/cc0-images/grapefruit-slice-332-332.jpg"],
  "model": "u2net",
  "outputFormat": "png",
  "backgroundColor": "transparent",
  "cropToSubject": false
}
```

Output example (from a real local run of this input):

```json
{
  "index": 1,
  "sourceUrl": "https://interactive-examples.mdn.mozilla.net/media/cc0-images/grapefruit-slice-332-332.jpg",
  "status": "ok",
  "url": "https://api.apify.com/v2/key-value-stores/WmCCWvM7evDVmpoin/records/0001-grapefruit-slice-332-332.png",
  "key": "0001-grapefruit-slice-332-332.png",
  "model": "u2net",
  "format": "png",
  "background": "transparent",
  "width": 332,
  "height": 332,
  "originalWidth": 332,
  "originalHeight": 332,
  "bytes": 208881,
  "originalBytes": 18122,
  "foregroundPercent": 64.4,
  "cropped": false,
  "processingMs": 1942,
  "error": null,
  "note": null
}
```

On Apify the `url` is a signed link that works without a token. A `SUMMARY` record counts delivered, failed and skipped images, and a `FAILED` record lists the reasons.

### Quality and limits

Measured locally on a handful of photos with both models (no claim beyond these):

- **Single objects on a distinct background** (a fruit slice, a painted hand, a car): both models give a clean cut-out.
- **A person with raised arms**: `u2net` kept both raised arms; `u2netp` lost most of them and cut the body off at the hips. Use `u2net` for people.
- **A dark elephant silhouette against a bright sunset**: `u2netp` found almost nothing; `u2net` found the head and back but dropped part of the lower body. Check such images by eye.
- **Hair, fur, glass, smoke and semi-transparent edges**: U2-Net returns a soft mask, edges can look slightly haloed. A GPU model such as BiRefNet is sharper on these.
- If the model finds almost no subject (under 0.1% of the image), the image is reported as an error and **not charged**. Use `foregroundPercent` to spot suspicious results: values near 0 or near 100 deserve a look.
- Images with their own transparency are flattened onto white before detection (the note says so). Animated GIFs: only the first frame. EXIF rotation is applied.
- Images over `maxLongSide` are downscaled, so the result is smaller than the original. Raise `maxLongSide` (max 8192) if you need full size.
- Typical speed: about 1 to 3 seconds per image once the run has started, plus 10 to 20 seconds of start-up.

### How much does it cost

**$0.008 per image delivered** (event `image-processed`, $8 per 1,000). Compute is included. No start fee. Failed, skipped, rejected and "no subject" images are free.

| Images | Price |
|---|---|
| 1,000 | $8 |
| 10,000 | $80 |
| 100,000 | $800 |

Set a maximum cost per run in Apify and the Actor stops cleanly when it is reached ("spending limit reached" in the status and the skipped rows).

### Use cases

1. White-background product photos for a shop or marketplace listing.
2. Transparent PNG logos, stickers and mock-up assets from existing photos.
3. Cut-outs of items from a catalogue feed before they go into a design template.
4. Preparing images for an ML dataset where the subject must be isolated.
5. Cut-outs of video stills: extract frames with the Video Frame Extractor, then run them through this Actor.

### FAQ

**Which model does it use and is the licence OK for commercial use?** rembg (MIT) with U2-Net or U2-Net-P (Apache-2.0). The weights are baked into the Actor image at build time; nothing is downloaded during a run. We do not use models with non-commercial licences.

**Why not BiRefNet or a GPU model?** GPU runs cost far more. This Actor is the cheap CPU option; edges are softer, and the README says where it struggles.

**Can I pass images from my own storage?** Only through a public (or signed) URL; the Actor cannot read private files.

**Does it work on HEIC, SVG or web pages?** No. HEIC and SVG are rejected, and a link to an HTML page returns an error without charge. Convert HEIC first.

**How big can an image be?** Up to 25 MB and 40 megapixels by default (100 MB and 50 megapixels at most). Larger pixel counts than 4096 on the long side are downscaled unless you raise `maxLongSide`.

**Does it keep my images?** Results are written to the run's key-value store (or the named store you choose) and follow Apify's data retention. The Actor does not send images anywhere else; downloads are limited to public internet addresses.

### Use with the Apify API, MCP, n8n or Make

Python:

```python
from apify_client import ApifyClient

client = ApifyClient("<APIFY_TOKEN>")
run = client.actor("<username>/background-remover").call(run_input={
    "imageUrls": ["https://example.com/product.jpg"],
    "backgroundColor": "#ffffff",
    "cropToSubject": True,
})
for row in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(row["status"], row["url"] or row["error"])
```

JavaScript:

```js
import { ApifyClient } from 'apify-client';

const client = new ApifyClient({ token: '<APIFY_TOKEN>' });
const run = await client.actor('<username>/background-remover').call({
  imageUrls: ['https://example.com/product.jpg'],
  outputFormat: 'webp',
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items.map((i) => i.url ?? i.error));
```

The same input works in the Apify MCP server (ask your assistant to "remove the background from this image URL"), in n8n through the Apify node, and in Make through the Apify app (run the Actor, then fetch dataset items).

### Related tools

- **Image Compressor & Resizer: Compress Images in Bulk**: shrink the cut-outs afterwards.
- **HEIC to JPG Converter: Convert HEIC/HEIF to JPG & PNG**: convert iPhone photos before removing backgrounds.
- **Download Images from URLs: Bulk Image & File Downloader**: collect the source images first.
- **Video Frame Extractor: Keyframes, Scenes & Thumbnails for AI**: pull still frames out of a video, then cut out the subject.

# Actor input Schema

## `imageUrls` (type: `array`):

Direct links to image files (JPEG, PNG, WebP, BMP, GIF, TIFF). Example: https://example.com/product.jpg. Duplicate links are processed once. Page links, HEIC and SVG are rejected without charge.

## `model` (type: `string`):

u2net (default) gave clearly better cut-outs on people and thin parts in our tests. u2netp is about twice as fast and fine for single products on plain backgrounds, but it can lose arms, legs and fine details. Both run on CPU and are Apache-2.0 licensed.

## `outputFormat` (type: `string`):

File type of each result. Both keep transparency. Example: png.

## `backgroundColor` (type: `string`):

'transparent' (default) or a solid colour as hex, for example #ffffff for white product shots or #f4f4f4. A few names work too: white, black, red, green, blue, yellow, gray.

## `cropToSubject` (type: `boolean`):

Trim the result to the bounding box of the detected subject, removing the empty margin. Example: true for tight product cut-outs.

## `maxImagesPerRun` (type: `integer`):

Hard cap on images processed in one run (1 to 2000). Images beyond the cap are listed as skipped and are free. Example: 100.

## `maxImageSizeMb` (type: `number`):

Larger downloads are rejected (free). Example: 25.

## `maxMegapixels` (type: `number`):

Images with more pixels than this are rejected before decoding (free), to protect memory. 40 megapixels is about 7000 x 5700. Example: 40.

## `maxLongSide` (type: `integer`):

Images longer than this are downscaled before processing, and the result has the smaller size. The note column says when this happened. Example: 4096.

## `imageTimeoutSecs` (type: `integer`):

Download plus processing time allowed for one image before it is reported as failed. Example: 120.

## `outputStoreName` (type: `string`):

Optional name of a key-value store that keeps the result files until you delete it, instead of the run's default store (which expires with the run's data retention). Example: my-cutouts.

## Actor input object example

```json
{
  "imageUrls": [
    "https://interactive-examples.mdn.mozilla.net/media/cc0-images/grapefruit-slice-332-332.jpg"
  ],
  "model": "u2net",
  "outputFormat": "png",
  "backgroundColor": "transparent",
  "cropToSubject": false,
  "maxImagesPerRun": 100,
  "maxImageSizeMb": 25,
  "maxMegapixels": 40,
  "maxLongSide": 4096,
  "imageTimeoutSecs": 120
}
```

# Actor output Schema

## `results` (type: `string`):

One row per image with its download link, size, subject share and status, as JSON, CSV, Excel and more.

## `records` (type: `string`):

Key-value store records: the result images, the run summary and notes on any failed images.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "imageUrls": [
        "https://interactive-examples.mdn.mozilla.net/media/cc0-images/grapefruit-slice-332-332.jpg"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("data-done-right/background-remover").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = { "imageUrls": ["https://interactive-examples.mdn.mozilla.net/media/cc0-images/grapefruit-slice-332-332.jpg"] }

# Run the Actor and wait for it to finish
run = client.actor("data-done-right/background-remover").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "imageUrls": [
    "https://interactive-examples.mdn.mozilla.net/media/cc0-images/grapefruit-slice-332-332.jpg"
  ]
}' |
apify call data-done-right/background-remover --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,data-done-right/background-remover"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/gNc1Awn6wUrSLLkEb/builds/XcXenNE6EYjCmfTLB/openapi.json
