# Image Upscaler API & Background Remover (Batch 2x/4x) (`leadsbrary/image-upscaler-background-remover-onnx`) Actor

Image upscaler API: batch upscale images 2x/4x and remove backgrounds from image URLs or datasets with open models on CPU. Returns PNG/WebP/JPEG links, sizes and status per image. From $1 per 1,000 images.

- **URL**: https://apify.com/leadsbrary/image-upscaler-background-remover-onnx.md
- **Developed by:** [Alexandre Manguis](https://apify.com/leadsbrary) (community)
- **Categories:** AI, Automation, E-commerce
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.00 / 1,000 results

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.
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

## Image Upscaler API & Background Remover (Batch, Open Models)

This **image upscaler API** enlarges images 2x or 4x and cuts out backgrounds in batch. Give it image URLs or an Apify dataset. You get back a link to each processed PNG, WebP or JPEG, plus its sizes, the models used and a status row per image. It runs open-licence models (Real-ESRGAN, U2-Net) with onnxruntime on CPU, so there is no GPU and no third-party API key.

### What does it do?

For every image URL it downloads the image, then runs one of three modes:

- **upscale** – enlarge 2x or 4x with a Real-ESRGAN model (`realesr-general-x4v3`, BSD-3-Clause).
- **remove-background** – transparent cut-out with U2-Net (`u2netp`, Apache-2.0).
- **both** – cut out the background, then enlarge the result.

The processed image is saved in the run's key-value store, and the dataset row holds its public URL and metadata.

### Who is it for / use cases

- E-commerce teams cleaning product photos: cut-outs on a white or custom colour background.
- Catalog and marketplace operators enlarging low-resolution supplier images.
- Developers who need an image upscaling or background-removal step in a pipeline, called via the Apify API.
- Anyone chaining it after a product or image scraper by passing that scraper's dataset ID.

### Features

- Batch input from a URL list and/or an existing Apify dataset (dot paths such as `images.0`; array fields are expanded).
- 2x or 4x upscaling, background removal, or both in one pass.
- Output as PNG, WebP or JPEG; optional hex background colour replaces transparency.
- Guard rails on size: inputs above a megapixel limit (default 0.5 MP) are downscaled, or rejected with an unbilled `TOO_LARGE` row.
- Failed images produce an error row (with `errorCode`) and are not billed.
- Optional proxy for image hosts that block direct requests.

### Input

| Field | Type | Default | Description |
|---|---|---|---|
| `imageUrls` | array of strings | – | Public http(s) URLs of JPEG, PNG or WebP images. |
| `datasetId` | string | – | Apify dataset whose rows contain image URLs. |
| `datasetUrlField` | string | `imageUrl` | Field with the URL; dot paths allowed; arrays expanded. |
| `mode` | `upscale` / `remove-background` / `both` | `upscale` | What to do with each image. |
| `scale` | integer 2–4 | `2` | Upscale factor (2 or 4); ignored for `remove-background`. |
| `outputFormat` | `png` / `webp` / `jpeg` | `png` | Transparency needs png or webp. |
| `backgroundColor` | string | – | Hex colour such as `#ffffff` to replace transparency. |
| `maxInputMegapixels` | number 0.1–4 | `0.5` | Larger inputs are downscaled or rejected. |
| `downscaleLargeInputs` | boolean | `true` | If off, oversized images return an unbilled `TOO_LARGE` row. |
| `maxResults` | integer 1–10000 | `10` | Maximum images to process (also caps spend). |
| `maxConcurrency` | integer 1–4 | `1` | Parallel images; processing is CPU and memory heavy. |
| `proxyConfiguration` | object | no proxy | Only needed if the image host blocks direct requests. |

You must provide `imageUrls` and/or `datasetId`; an empty input fails with a clear message.

#### Example input

```json
{
  "imageUrls": ["https://picsum.photos/id/10/400/300.jpg"],
  "mode": "upscale",
  "scale": 2,
  "outputFormat": "png",
  "maxResults": 2
}
```

To process a dataset from another scraper instead, set `datasetId` and `datasetUrlField` (for example `images.0`).

### Output

#### Example output

One dataset row per image. Sample from a real run (`upscale`, 2x; store ID anonymized):

```json
{
  "inputUrl": "https://picsum.photos/id/10/400/300.jpg",
  "status": "success",
  "mode": "upscale",
  "scale": 2,
  "outputUrl": "https://api.apify.com/v2/key-value-stores/STORE_ID/records/img-0002.png",
  "outputKey": "img-0002.png",
  "outputFormat": "png",
  "inputWidth": 400,
  "inputHeight": 300,
  "outputWidth": 800,
  "outputHeight": 600,
  "wasDownscaled": false,
  "outputBytes": 700501,
  "processingMs": 63425,
  "models": ["realesr-general-x4v3 (BSD-3-Clause)"],
  "errorCode": null,
  "errorMessage": null,
  "processedAt": "2026-10-05T21:56:54.654Z"
}
```

#### Test runs

Proof runs on Apify covered all three modes:

- **both, 4x** (2 images, succeeded): a 500×349 sunflower became 2000×1396 with `u2netp (Apache-2.0)` plus the upscaler.
- **remove-background** (3 images, succeeded): a 500×453 apple kept its size (`scale` is `null`).
- **error handling** (4 inputs, 1 success, 3 error rows): HTTP 404, a URL that returned HTML instead of an image, and an HTTP 429 from the image host. Each is reported in its own row.

#### Output fields & fill rates

Measured on the Apify medium test run (8 rows) and proof runs. Error fields are filled only on failed rows; `scale` is `null` in `remove-background` mode.

| Field | Fill rate | Notes |
|---|---|---|
| `inputUrl` | 100% | Source URL. |
| `status` | 100% | `success` or error status. |
| `mode` | 100% | Mode used. |
| `scale` | 100% (0% in remove-background) | Upscale factor. |
| `outputUrl` | 100% | Public link to the result in the key-value store. |
| `outputKey` | 100% | Record key in the key-value store. |
| `outputFormat` | 100% | png, webp or jpeg. |
| `inputWidth`, `inputHeight` | 100% | Source size in pixels. |
| `outputWidth`, `outputHeight` | 100% | Result size in pixels. |
| `wasDownscaled` | 100% | True if the input was reduced to the megapixel limit. |
| `outputBytes` | 100% | Result file size. |
| `processingMs` | 100% | Processing time. |
| `models` | 100% | Models used, with licence. |
| `errorCode`, `errorMessage` | 0% on successful rows | Filled only on failed rows. |
| `processedAt` | 100% | ISO 8601 timestamp. |

### How to use via API

#### Configuration

All settings are in the input table above; `mode`, `scale` and `maxResults` are the ones most users change. Replace `YOUR_TOKEN` below with your Apify API token.

#### Code examples

**curl**

```bash
curl -X POST "https://api.apify.com/v2/acts/ACTOR_ID/run-sync-get-dataset-items?token=YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"imageUrls":["https://picsum.photos/id/10/400/300.jpg"],"mode":"upscale","scale":2}'
```

**JavaScript**

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

const client = new ApifyClient({ token: 'YOUR_TOKEN' });
const run = await client.actor('ACTOR_ID').call({
    imageUrls: ['https://picsum.photos/id/10/400/300.jpg'],
    mode: 'remove-background',
    outputFormat: 'png',
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items[0].outputUrl);
```

**Python**

```python
from apify_client import ApifyClient

client = ApifyClient("YOUR_TOKEN")
run = client.actor("ACTOR_ID").call(run_input={
    "imageUrls": ["https://picsum.photos/id/10/400/300.jpg"],
    "mode": "both",
    "scale": 4,
    "downscaleLargeInputs": True,
})
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item["outputUrl"], item["status"])
```

`ACTOR_ID` is the Actor's ID or `username~actor-name`.

### Pricing

#### Pay per event

Pay per event: you are billed one `image-processed` event for each successfully processed image. Error rows (failed downloads, non-images, oversized inputs when downscaling is off) are not billed.

| Apify plan | Price per 1,000 images |
|---|---|
| Free | $1.50 |
| Bronze | $1.30 |
| Silver | $1.15 |
| Gold and above | $1.00 |

Platform usage (compute) is charged by Apify separately. In the test runs it was small: 2 images cost about $0.004 in total platform usage, and the 3-image background-removal run about $0.0006. Use `maxResults` to cap spend.

### Troubleshooting

- **Run fails with "Invalid input"**: provide `imageUrls` and/or `datasetId`.
- **`DOWNLOAD_FAILED` / HTTP 404 or 429**: the host refused or rate-limited the request. Retry later, or enable `proxyConfiguration` (a datacenter proxy was enough in testing).
- **`NOT_AN_IMAGE` / `UNSUPPORTED_FORMAT`**: the URL returned HTML or a format other than JPEG, PNG or WebP (SVG fixtures are not supported).
- **`TOO_LARGE`**: raise `maxInputMegapixels` (up to 4) or turn on `downscaleLargeInputs`.
- **Slow or timed-out runs**: this is CPU inference. Speed varies by image: measured per-image times ranged from about 0.6 s (background removal) to about 63 s (one 2x upscale). The medium test run (8 images) hit the 300 s test limit before finishing, so split large batches into several runs and keep `maxConcurrency` low.
- **Transparent areas look black or white in JPEG**: JPEG has no transparency. Use png or webp, or set `backgroundColor`.

### FAQ

**Which models does it use?** Real-ESRGAN `realesr-general-x4v3` (BSD-3-Clause) for upscaling and U2-Net `u2netp` (Apache-2.0) for background removal. Each row lists the models used.

**Do I need a GPU or an API key?** No. It runs on CPU inside the Actor.

**Where are the processed images?** In the run's key-value store; the row's `outputUrl` links to each file.

**Can it process images behind a login?** No. Only public image URLs are fetched.

**Can I feed it the output of another scraper?** Yes: set `datasetId` and `datasetUrlField`.

### Keywords

image upscaler api, image upscaler, batch image upscaler, ai image upscaling, upscale images from url, 2x 4x upscale, real-esrgan, background remover, remove background from image, background removal api, transparent png, product photo cleanup, bulk image processing, onnx image processing

### Hashtags

\#imageupscaler #upscaleimages #backgroundremover #removebackground #realesrgan #u2net #onnx #ecommerce #productphotos #batchprocessing #apify #imageprocessing

# Changelog

This Actor's version history is a separate document: https://apify.com/leadsbrary/image-upscaler-background-remover-onnx/changelog.md

# Actor input Schema

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

Public http(s) URLs of JPEG, PNG or WebP images. Use this and/or a dataset below.

## `datasetId` (type: `string`):

ID of an Apify dataset whose rows contain image URLs (for example the output of a product scraper).

## `datasetUrlField` (type: `string`):

Field holding the image URL; dot paths allowed (e.g. images.0). A field containing an array of URLs is expanded.

## `mode` (type: `string`):

upscale: enlarge. remove-background: transparent cut-out. both: cut-out then enlarge.

## `scale` (type: `integer`):

2 or 4 (ignored for remove-background).

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

Transparency needs png or webp; jpeg is flattened onto the background colour (white by default).

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

Optional hex colour such as #ffffff to replace transparency after background removal.

## `maxInputMegapixels` (type: `number`):

Larger inputs are downscaled (or rejected, see below) to bound time and cost. 0.1 to 4.

## `downscaleLargeInputs` (type: `boolean`):

If off, images above the megapixel limit return an unbilled TOO_LARGE row.

## `maxResults` (type: `integer`):

Process at most this many images (also caps your spending).

## `maxConcurrency` (type: `integer`):

Keep low: processing is CPU and memory heavy.

## `proxyConfiguration` (type: `object`):

Optional. Only needed if the image host blocks direct requests; datacenter proxy was enough in testing.

## Actor input object example

```json
{
  "imageUrls": [
    "https://commons.wikimedia.org/wiki/Special:FilePath/Cat_November_2010-1a.jpg?width=400",
    "https://picsum.photos/id/10/400/300.jpg"
  ],
  "datasetUrlField": "imageUrl",
  "mode": "upscale",
  "scale": 2,
  "outputFormat": "png",
  "maxInputMegapixels": 0.5,
  "downscaleLargeInputs": true,
  "maxResults": 2,
  "maxConcurrency": 1,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

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

No description

# 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://commons.wikimedia.org/wiki/Special:FilePath/Cat_November_2010-1a.jpg?width=400",
        "https://picsum.photos/id/10/400/300.jpg"
    ],
    "datasetUrlField": "imageUrl",
    "mode": "upscale",
    "scale": 2,
    "maxInputMegapixels": 0.5,
    "maxResults": 2,
    "proxyConfiguration": {
        "useApifyProxy": false
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("leadsbrary/image-upscaler-background-remover-onnx").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://commons.wikimedia.org/wiki/Special:FilePath/Cat_November_2010-1a.jpg?width=400",
        "https://picsum.photos/id/10/400/300.jpg",
    ],
    "datasetUrlField": "imageUrl",
    "mode": "upscale",
    "scale": 2,
    "maxInputMegapixels": 0.5,
    "maxResults": 2,
    "proxyConfiguration": { "useApifyProxy": False },
}

# Run the Actor and wait for it to finish
run = client.actor("leadsbrary/image-upscaler-background-remover-onnx").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://commons.wikimedia.org/wiki/Special:FilePath/Cat_November_2010-1a.jpg?width=400",
    "https://picsum.photos/id/10/400/300.jpg"
  ],
  "datasetUrlField": "imageUrl",
  "mode": "upscale",
  "scale": 2,
  "maxInputMegapixels": 0.5,
  "maxResults": 2,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}' |
apify call leadsbrary/image-upscaler-background-remover-onnx --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,leadsbrary/image-upscaler-background-remover-onnx"
        }
    }
}
```

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/AxHswV2JqqfEOOOPD/builds/gDZ9g06DCXnPrjcgS/openapi.json
