# AI Image Upscaler & Background Remover (CPU) (`singgendarhan/ai-image-upscaler-background-remover`) Actor

Upscale images 2x-4x with Real-ESRGAN and remove backgrounds with U2-Net in one Actor. Bulk URLs in, downloadable PNG/WebP/JPEG out, one dataset row per image. Pay only for successfully processed images.

- **URL**: https://apify.com/singgendarhan/ai-image-upscaler-background-remover.md
- **Developed by:** [Nick Na](https://apify.com/singgendarhan) (community)
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $8.00 / 1,000 image upscaled (per 0.25 mp)s

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

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

## AI Image Upscaler & Background Remover (CPU)

Upscale images **2x, 3x or 4x** with Real-ESRGAN, **remove backgrounds** with U²-Net, or do **both in one pass**, for one image or thousands. Give it image URLs and get back download links to PNG, WebP or JPEG files, plus one clean dataset row per image. **You only pay for images that were processed successfully.** Broken links, non-images and oversized files cost nothing.

Built for e-commerce sellers, catalog and marketplace teams, and no-code automations (n8n, Make, Zapier). It also works with AI agents through Apify's MCP server: clear inputs, predictable outputs, stable error codes.

### What it does

- **AI upscaling (2x / 3x / 4x).** Real-ESRGAN `realesr-general-x4v3` sharpens detail and removes JPEG blockiness and noise. An adjustable **denoise strength** lets you keep grain or wipe it.
- **Background removal.** Cuts out the main subject onto a transparent background (PNG/WebP), or onto any solid color, such as pure white `#FFFFFF`.
- **Both at once.** Cut out first, then upscale. You get one file.
- **Marketplace-style square images.** Crop to the product, center it on a square canvas with a margin, and fill with white. That gives you listing-ready main images in one call.
- **Transparent PNGs stay transparent** when upscaled.
- **Bulk and robust.** Downloads run in parallel. Each download is retried up to 3 times, with backoff that honors `Retry-After`. Content type and size are validated. One bad image never fails the run: it gets a row with an `errorCode`.
- **Pay only for results.** We charge after the output file is saved, never for failures.
- **Spending cap respected.** If you set a maximum cost per run, the Actor stops cleanly before going over and marks the remaining images `skipped`.

### Use cases

- **E-commerce listings.** Turn supplier photos into white-background square product images. Upscale small images so zoom works.
- **Catalog clean-up.** Process a whole product feed of image URLs overnight.
- **Print and design.** Enlarge artwork, icons or photos 4x before printing or placing in layouts.
- **Automations.** n8n / Make / Zapier flows: "new product image → cut out → upscale → upload to store".
- **AI agents.** An agent passes image URLs and reads back `outputUrl`, `status` and `errorCode` from the dataset.
- **Restoration.** Sharpen low-resolution thumbnails, screenshots and old scans.

### How to use

1. Paste one or more **image URLs**. Links to files in an Apify key-value store work too.
2. Pick an **operation**: *Upscale*, *Remove background*, or *Remove background, then upscale*.
3. Choose the **upscale factor**, the **output format** and, optionally, a **background color** and **square canvas**.
4. Click **Start**. The results appear in the **Output** tab: a preview, a download link and dimensions for every image.

Supported inputs: JPEG, PNG (including transparent), WebP, GIF (first frame), BMP, TIFF, AVIF.

#### Input example

```json
{
    "imageUrls": [
        "https://images-assets.nasa.gov/image/as11-40-5903/as11-40-5903~small.jpg",
        "https://example.com/products/sku-123.jpg"
    ],
    "operation": "remove_background_and_upscale",
    "scale": 2,
    "outputFormat": "jpeg",
    "backgroundColor": "#FFFFFF",
    "squareCanvas": true,
    "canvasMarginPercent": 5
}
```

| Field | Default | What it does |
|---|---|---|
| `imageUrls` | none | Public http(s) image links. Objects like `{"url": "..."}` are accepted too. |
| `operation` | `upscale` | `upscale`, `remove_background` or `remove_background_and_upscale` |
| `scale` | `4` | 2, 3 or 4 |
| `outputFormat` | `png` | `png`, `webp` or `jpeg` |
| `backgroundColor` | none (transparent) | Hex color used to fill transparent areas. JPEG output always gets a fill, white by default. |
| `squareCanvas` / `canvasMarginPercent` | `false` / `5` | Crop to the subject and center it on a square canvas. Needs background removal. |
| `keyValueStoreId` / `keyValueStoreKeys` | none | Process image files stored in an Apify key-value store |
| `denoiseStrength` | `0.5` | 0 keeps texture, 1 removes noise and JPEG artifacts most |
| `outputQuality` | `90` | JPEG/WebP quality. 100 makes WebP lossless. |
| `maxUpscaleInputMegapixels` | `2` | Larger images are not upscaled and get an error instead (max 4) |
| `maxFileSizeMb` | `25` | Download size limit (max 100) |
| `downloadTimeoutSecs` | `30` | Per-attempt download timeout |

#### Output example

Each output file is saved in the run's key-value store, with a link in the dataset (one item per input image):

```json
{
    "index": 0,
    "source": "https://images-assets.nasa.gov/image/as11-40-5903/as11-40-5903~small.jpg",
    "sourceType": "url",
    "operation": "remove_background_and_upscale",
    "scale": 4,
    "status": "succeeded",
    "outputUrl": "https://api.apify.com/v2/key-value-stores/<storeId>/records/image-0000-as11-40-5903-small.png",
    "outputKey": "image-0000-as11-40-5903-small.png",
    "outputFormat": "png",
    "outputBytes": 10424662,
    "inputFormat": "jpeg",
    "inputWidth": 640,
    "inputHeight": 624,
    "outputWidth": 2560,
    "outputHeight": 2496,
    "downloadMs": 387,
    "processingMs": 8927,
    "totalMs": 9314,
    "chargedEvents": { "background-removed": 1, "image-upscaled": 2 },
    "errorCode": null,
    "errorMessage": null
}
```

A failed image looks like this. It is never charged:

```json
{ "index": 4, "source": "https://example.com/missing.jpg", "status": "failed", "outputUrl": null,
  "chargedEvents": {}, "errorCode": "DOWNLOAD_FAILED", "errorMessage": "HTTP 404 Not Found for https://example.com/missing.jpg." }
```

The `OUTPUT` record in the key-value store holds a run summary: `total`, `succeeded`, `failed`, `skipped`, `chargedEvents`.

**Error codes:** `INVALID_URL`, `URL_NOT_ALLOWED`, `DOWNLOAD_FAILED`, `DOWNLOAD_TIMEOUT`, `NOT_AN_IMAGE`, `UNSUPPORTED_FORMAT`, `CORRUPT_IMAGE`, `FILE_TOO_LARGE`, `IMAGE_TOO_LARGE`, `IMAGE_TOO_LARGE_FOR_UPSCALE`, `OUTPUT_TOO_LARGE`, `KVS_RECORD_NOT_FOUND`, `OUT_OF_MEMORY`, `PROCESSING_FAILED`, and `RUN_STOPPED` (skipped because the run hit your cost limit or was aborted).

### Pricing

This Actor uses **pay-per-event** pricing. You pay for results, not for compute time:

| Event | Price | When |
|---|---|---|
| Upscaled image | **$0.008 per started 0.25 MP of input** | Each successfully upscaled image. 0.25 MP is about 500x500 px. |
| Background removed | **$0.004 per image** | Each successful cut-out, any size up to 40 MP |
| Actor start | $0.00005 per GB of memory | Once per run (Apify's standard start fee) |

Examples:

- 1,000 images ≤ 500x500 upscaled: **$8**
- 1,000 cut-outs: **$4**
- One 1000x1000 photo upscaled: 4 units = **$0.032**
- One 640x624 photo cut out and upscaled 4x: $0.004 + 2 x $0.008 = **$0.020**
- Failed or skipped images: **$0**

**Why per megapixel?** The AI model's work grows with the number of input pixels. 2x and 4x cost the same, because both run the same 4x network (2x is resized down from it). Small images, which are the usual upscaling case, stay very cheap. Large ones are billed fairly. Set **Max cost per run** in the run options to cap spending, and the Actor will stop cleanly at that limit.

### Limits and good to know

- **Upscale input size.** Up to 2 MP by default (for example 1600x1250), configurable up to 4 MP. 4x of 4 MP is a 64 MP output, so larger inputs are refused with a clear error. **Background removal** accepts inputs up to 40 MP.
- **WebP** outputs are limited to 16,383 px per side, and **JPEG** to 65,535 px.
- **Speed (CPU).** With the default 4 GB of memory (1 CPU), expect roughly 1–2 s per background removal and 5–15 s per upscaled 0.25–0.5 MP image. More memory runs more images in parallel. This is a CPU Actor: slower than GPU tools, much cheaper per image.
- **File sizes.** 4x PNGs of photos are big (about 10 MB for 2560x2496). Choose WebP or JPEG for 20–60x smaller files.
- **Where your files live.** In the run's default key-value store. Unnamed storages expire after 7 days unless your plan says otherwise, so download or copy what you need.
- **Quality notes.** Like all Real-ESRGAN models, small text and logos can come out distorted, and faces are not specially restored. Background removal works best on a clear main subject. Very fine hair or transparent objects get soft edges.
- **Public URLs only.** Links to private or local network addresses are blocked.

### Use it from code, n8n, Make or agents

Run it synchronously and get the dataset back in one HTTP call (best for small batches; synchronous runs time out after 300 s):

```bash
curl -X POST "https://api.apify.com/v2/acts/<ACTOR_ID>/run-sync-get-dataset-items?token=<YOUR_APIFY_TOKEN>" \
  -H "Content-Type: application/json" \
  -d '{"imageUrls": ["https://example.com/photo.jpg"], "operation": "remove_background", "outputFormat": "png"}'
```

In **n8n** or **Make**, use the Apify app/node "Run Actor", pass the same JSON, then read `outputUrl` from the dataset items. AI agents can use the Actor through the Apify MCP server: the input and dataset schemas describe every field.

### FAQ

**Do I pay for images that fail?** No. Charges happen only after the output file is saved. Every failure is listed with an error code and costs $0.

**Is 4x more expensive than 2x?** No. The price depends only on the input size.

**What happens to transparency with JPEG output?** JPEG has no transparency, so transparent areas are filled with your `backgroundColor`, or white.

**Can I process files that are not online?** Yes. Upload them to an Apify key-value store and pass `keyValueStoreId` plus `keyValueStoreKeys`.

**Can I use the results commercially?** The models are open-source under permissive licenses: Real-ESRGAN is BSD-3-Clause and U²-Net is Apache-2.0. You need the rights to the images you upload.

**Do you keep my images?** The Actor processes images in memory and writes results only to your own run's storage. It keeps no other copies. Logs contain image URLs and timings, not image data.

**Why CPU and not GPU?** CPU keeps the price per image low and the runs reliable. For the typical small-image upscale and for background removal, it is fast enough.

**Something looks wrong?** Open an issue on the Issues tab with the run ID. We read every one.

### Credits

- Real-ESRGAN by Xintao Wang et al. (BSD-3-Clause), https://github.com/xinntao/Real-ESRGAN
- U²-Net by Xuebin Qin et al. (Apache-2.0), https://github.com/xuebinqin/U-2-Net. ONNX export by rembg (MIT), https://github.com/danielgatis/rembg
- The example image is NASA photo AS11-40-5903 (public domain). NASA does not endorse this Actor.

# Changelog

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

# Actor input Schema

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

Public http(s) links to the images to process, one per line. Supported formats: JPEG, PNG (including transparent), WebP, GIF (first frame), BMP, TIFF, AVIF. Links to files in an Apify key-value store work too.

## `operation` (type: `string`):

What to do with each image. 'Upscale' makes it 2-4x larger and sharper (Real-ESRGAN). 'Remove background' cuts out the main subject onto a transparent (or solid-color) background (U2-Net). 'Remove background, then upscale' does both and returns one image.

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

How many times larger the output should be (2, 3 or 4). Used only when the operation includes upscaling. The price depends on the input size, not on the factor (2x and 4x run the same network).

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

File format of the processed images. PNG and WebP keep transparency. JPEG has no transparency, so a removed background is filled with the background color (white by default).

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

Optional hex color (for example #FFFFFF for a pure white e-commerce background) to fill transparent areas with. Leave empty to keep transparency (PNG/WebP).

## `squareCanvas` (type: `boolean`):

E-commerce layout: crop to the cut-out subject and center it on a square canvas with a margin. Combine with background color #FFFFFF for marketplace-style main images. Needs an operation with background removal.

## `canvasMarginPercent` (type: `number`):

Empty space around the subject on each side of the square canvas, as a percentage of the canvas size (5 means the subject spans about 90% of the canvas).

## `keyValueStoreId` (type: `string`):

Optional. ID or name of an Apify key-value store that holds image files to process (use together with 'Record keys'). Leave empty if you only use image URLs.

## `keyValueStoreKeys` (type: `array`):

Keys of the image records in the key-value store above, one per line (for example product-001.jpg).

## `denoiseStrength` (type: `number`):

0 keeps grain and fine texture, 1 removes noise and JPEG artifacts most aggressively. 0.5 is the Real-ESRGAN default.

## `outputQuality` (type: `integer`):

Compression quality for JPEG and WebP outputs (1-100). 100 makes WebP lossless. Ignored for PNG.

## `maxUpscaleInputMegapixels` (type: `number`):

Images larger than this (width x height / 1,000,000) are not upscaled and get a clear error instead. Default 2 MP (e.g. 1600x1250), maximum 4 MP. Background removal works on images up to 40 MP regardless.

## `maxFileSizeMb` (type: `number`):

Downloads larger than this are skipped with a FILE_TOO_LARGE error.

## `downloadTimeoutSecs` (type: `integer`):

Timeout for each download attempt. Failed downloads are retried up to 3 times with backoff (honoring Retry-After).

## Actor input object example

```json
{
  "imageUrls": [
    "https://images-assets.nasa.gov/image/as11-40-5903/as11-40-5903~small.jpg",
    "https://example.com/products/sku-123.jpg"
  ],
  "operation": "remove_background_and_upscale",
  "scale": 4,
  "outputFormat": "png",
  "squareCanvas": false,
  "canvasMarginPercent": 5,
  "denoiseStrength": 0.5,
  "outputQuality": 90,
  "maxUpscaleInputMegapixels": 2,
  "maxFileSizeMb": 25,
  "downloadTimeoutSecs": 30
}
```

# Actor output Schema

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

Status, output URL, dimensions, timings and error details for every input image.

## `images` (type: `string`):

The output images (PNG/WebP/JPEG) in the run's key-value store.

## `summary` (type: `string`):

Counts of succeeded, failed and skipped images and the events charged.

# 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://images-assets.nasa.gov/image/as11-40-5903/as11-40-5903~small.jpg"
    ],
    "operation": "remove_background_and_upscale"
};

// Run the Actor and wait for it to finish
const run = await client.actor("singgendarhan/ai-image-upscaler-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://images-assets.nasa.gov/image/as11-40-5903/as11-40-5903~small.jpg"],
    "operation": "remove_background_and_upscale",
}

# Run the Actor and wait for it to finish
run = client.actor("singgendarhan/ai-image-upscaler-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://images-assets.nasa.gov/image/as11-40-5903/as11-40-5903~small.jpg"
  ],
  "operation": "remove_background_and_upscale"
}' |
apify call singgendarhan/ai-image-upscaler-background-remover --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,singgendarhan/ai-image-upscaler-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/lDvpEcHlPyDMUeA80/builds/NbKYariPZjM1kHD8k/openapi.json
