# AI Image Upscaler for Print: 300 DPI for POD & KDP (`vncntlabs/print-ready-upscaler`) Actor

AI image upscaler that makes print-ready files at the exact size each platform needs: Merch by Amazon 4500x5400 PNG, Redbubble, TeePublic, Printful, Printify, Etsy wall art and KDP covers. Keeps transparency with no halos, sets 300 DPI + sRGB, fits file-size limits. Real-ESRGAN, commercial use OK.

- **URL**: https://apify.com/vncntlabs/print-ready-upscaler.md
- **Developed by:** [vncntlabs Labs](https://apify.com/vncntlabs) (community)
- **Categories:** E-commerce, AI, For creators
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $60.00 / 1,000 image upscaleds

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 for Print: upscale images to 300 DPI for print on demand and KDP

**Upscale images for print with AI.** Turn small or low-quality designs into print-ready files at the exact size each print-on-demand platform asks for: a 1024 px AI-art PNG becomes a 4500 x 5400 px, 300 DPI transparent PNG under 25 MB for Merch by Amazon, and the same run can output Redbubble, TeePublic, Printful, Printify, Etsy wall-art and KDP cover sizes. Real-ESRGAN upscaling (commercial use allowed), halo-free transparency, sRGB conversion and automatic file-size fitting.

The tool AI-upscales with **Real-ESRGAN**. Its BSD-3-Clause license allows commercial use. Then it does the fiddly parts that generic upscalers skip:

- **Exact platform sizes.** Amazon Merch, Redbubble (12 products), TeePublic, Printful, Printify, Etsy printable wall art (8×10 to 24×36 in, A4–A2), Kindle eBook covers, and a **KDP paperback cover calculator** (trim size + page count + paper → full-wrap size with bleed, as a PDF).
- **Transparency done right.** The alpha channel is upscaled by AI too, so cut-out edges stay crisp. Colours are bled under transparent pixels, so you get **no dark or white halos** around your design on a coloured shirt.
- **Correct print metadata.** The DPI is written into the file, colours are converted to **sRGB** (CMYK, Adobe RGB and other ICC profiles are handled), and an sRGB profile is embedded. Camera and editor metadata is stripped (optional).
- **File-size limits.** The tool compresses until the file fits (Merch's 25 MB by default, or any limit you set). PNG gets maximum lossless compression first, then an optional 256-colour reduction. JPG and PDF use the highest quality that fits.
- **Fit modes.** *Contain* keeps the whole design and pads with transparency. *Cover* fills the canvas and crops. *Exact* stretches. Alignment can be top, center or bottom. Empty transparent margins are trimmed automatically for apparel.
- **Safe batch processing.** Every image gets its own row with a download link, the size in px and inches, DPI, file size and warnings. **Images that fail are listed with the reason and are never charged.**

### Who it's for

Amazon Merch on Demand, Redbubble, TeePublic, Spreadshirt, Etsy + Printful/Printify sellers, KDP low-content and cover designers, and anyone with designs that are too small to print. Typical sources:

- AI art (Midjourney, DALL·E, Stable Diffusion: 1024–1536 px)
- old designs made at 72 DPI
- client logos
- Canva exports
- images saved from the web that you own the rights to

### How to use

1. Paste **image URLs**, upload one image, or pick a **key-value store** with many images.
2. Choose a **print target** (default: Amazon Merch 4500 × 5400).
3. Run. Download the files from the **Download** column, or from the run's key-value store.

#### Input example

```json
{
  "imageUrls": ["https://example.com/my-design.png"],
  "preset": "merch-standard",
  "fitMode": "contain",
  "anchor": "top"
}
```

KDP paperback cover (6 × 9 in, 300 pages, white paper → 12.926 × 9.25 in = 3878 × 2775 px PDF):

```json
{ "imageUrls": ["https://example.com/full-wrap.jpg"], "preset": "kdp-paperback-cover",
  "kdpTrimSize": "6x9", "kdpPageCount": 300, "kdpPaperType": "white", "fitMode": "cover" }
```

#### Output example (one dataset row per image)

```json
{
  "index": 1, "status": "success",
  "outputUrl": "https://api.apify.com/v2/key-value-stores/…/records/0001-my-design-merch-standard.png",
  "width": 4500, "height": 5400, "dpi": 300, "printWidthInches": 15, "printHeightInches": 18,
  "format": "png", "hasTransparency": true, "fileSizeMB": 3.64, "maxFileSizeMB": 25,
  "inputWidth": 1024, "inputHeight": 1229, "method": "ai", "scaleFactor": 4.43,
  "colorProfile": "sRGB IEC61966-2.1", "warnings": [], "error": null
}
```

### Print targets

| Preset | Pixels | Notes / source |
|---|---|---|
| `merch-standard` | 4500 × 5400 PNG, 300 DPI, ≤ 25 MB | Amazon Merch standard t-shirt/hoodie |
| `redbubble-tee` / `-premium-tee` / `-apparel` | 3873 × 4814 / 2875 × 3900 / 2400 × 3200 | help.redbubble.com article 202270679 |
| `redbubble-sticker` / `-pillow` / `-home-large` | 2800² / 3225² / 7632 × 6480 | stickers, throw pillows, duvet/tapestry/blanket |
| `redbubble-jigsaw` / `-mug` / `-tall-mug` | 9075 × 6201 / 2700 × 1120 / 2700 × 1624 | |
| `redbubble-clock` / `-coaster` / `-pin` | 2940² / 1860² / 1000² | |
| `teepublic` | 5000 × 5500 at 150 DPI | TeePublic "all products" size |
| `printful-tee`, `printify-tee` | 4500 × 5400 | 15 × 18 in at 300 DPI (check your Printify blueprint) |
| `print-8x10` … `print-24x36`, `print-a4/a3/a2` | 2400 × 3000 … 7200 × 10800 | Etsy printable wall art, JPG |
| `kdp-ebook-cover` | 1600 × 2560 JPG | KDP's recommended 1.6:1 |
| `kdp-paperback-cover` | computed | 0.125 + trim + spine + trim + 0.125 in wide; spine = pages × 0.002252 (white / standard colour), 0.0025 (cream), 0.002347 (premium colour); 24–830 pages; PDF |
| `custom` | any W × H px, or inches × DPI | up to 16000 px per side / 120 MP |
| `scale` | ×1 – ×8 | keeps the aspect ratio |

Platforms change their specs. Check the platform's current help page before a big batch.

### How it decides what to do

- **Needs ≥ 1.25× enlargement →** AI. Real-ESRGAN ×4, then an exact Lanczos resize to the target. **Above 6×** (e.g. a 250 px logo for Merch) it runs two AI passes.
- **Needs < 1.25× →** a high-quality Lanczos resize. This is just as good and much faster. The image is still converted, DPI-tagged, fitted and size-limited.
- **After AI →** a colour-fidelity correction (back-projection), so pinks, navies and skin tones stay the colour you designed. Raw Real-ESRGAN tends to darken or tint them.

### Quality (our own tests)

We drew test designs at 2000 × 2400 px, shrank them to 25 %, upscaled them back, and compared each result to the original. The higher the PSNR, the closer to the original.

| Test image | Plain Lanczos | **AI general (default)** | AI illustration |
|---|---|---|---|
| Typography with outlines + small print | 29.3 dB | **36.9 dB** | 33.4 dB |
| Thin line art / mandala | 24.5 dB | **30.4 dB** | 26.9 dB |
| Sticker illustration, soft shadow | 29.3 dB | **35.2 dB** | 33.0 dB |
| Same illustration, JPEG-damaged source | 28.8 dB | **32.7 dB** | 31.3 dB |
| Neon glow (semi-transparent) | 35.5 dB | **38.1 dB** | 35.2 dB |
| Wildlife photo (NASA, public domain) | 33.0 dB | 32.4 dB | 32.8 dB |

On designs, text and line art the AI result is much sharper, with clean edges and no halos. On photos it removes JPEG blockiness and noise, but it can't invent detail that was never there. Faces and fine textures will look smooth, not "re-photographed".

### Speed, memory and limits

- **CPU only** (Apify has no GPUs). A typical Merch job, 1024 px design → 4500 × 5400 transparent PNG, takes about **40 s at 8 GB, 100 s at 4 GB (default), 3 min at 2 GB, and 5–6 min at 1 GB**. Small targets (stickers, pins) take a few seconds per image.
- Memory: 4500 × 5400 needs about 0.4 GB. The largest presets (24 × 36 in, jigsaw) need about 1 GB and are refused below 2 GB, with a clear message and no charge.
- Inputs:
  - PNG, JPG, WEBP, GIF (first frame on request), BMP, TIFF
  - max 50 MB (configurable up to 100 MB) and 50 MP
  - at least 16 px per side
- Rejected inputs (never charged): SVG/PDF inputs (export them to PNG first), HTML "share" pages instead of image links, animated images (unless you pick first frame), fully transparent images.
- Converted, with a warning: 16-bit images are reduced to 8-bit. CMYK without an embedded profile is converted with a generic formula; convert in your editor if exact colours matter.
- Hardcover KDP covers are not computed. Use KDP's cover calculator with `custom`.
- **Rights:** only upscale artwork you own or are licensed to use. Upscaling does not make an image copyright-free.

### Pricing

Pay per successfully upscaled image, with platform usage included. Each image is charged **exactly one** of these events, never both:

| Output size | Event | Price | Examples |
|---|---|---|---|
| Up to 40 megapixels | `image-upscaled` | **$0.06** | Merch 4500×5400 (24.3 MP), TeePublic 5000×5500 (27.5 MP), Printful/Printify, Redbubble tees/stickers/mugs, 8×10–18×24 in prints (18×24 = 38.9 MP), A4–A2, KDP covers |
| Over 40 megapixels (width × height > 40,000,000) | `large-image-upscaled` | **$0.10** | 24×36 in poster at 300 DPI (7200×10800 = 77.8 MP), Redbubble duvet/tapestry (49.5 MP), jigsaw (56.3 MP) |

Failed, rejected and skipped images cost nothing. Set "Maximum cost per run" and the Actor checks the right price for each image before processing it, then stops cleanly before going over your limit. Every dataset row shows `pricingTier` (`standard`/`large`) and `chargedEvent`.

Examples: 100 Merch designs = $6.00 · 1,000 sticker files = $60 · 50 posters at 24×36 in = $5.00.

### Models and licenses

| Option | Network | Weights | License |
|---|---|---|---|
| `general` (default) | Real-ESRGAN `realesr-general-x4v3` (SRVGGNetCompact) | official release v0.2.5.0, github.com/xinntao/Real-ESRGAN | BSD-3-Clause |
| `illustration` | Real-ESRGAN `realesr-animevideov3` | official release v0.2.5.0 | BSD-3-Clause |

The weights were converted to ONNX without modification and run with ONNX Runtime (MIT). The BSD-3-Clause license allows commercial use and redistribution with attribution. It is included in the Actor image (`models/LICENSE-Real-ESRGAN.txt`). Copyright (c) 2021, Xintao Wang.

### FAQ

**Will Amazon accept the files?** The files match Merch's published requirements: 4500 × 5400 PNG, sRGB, 300 DPI, under 25 MB. Content review is up to Amazon.

**Is it a vectorizer?** No. The output is a sharp raster. For logos that must scale to billboard size, use a vector tool.

**Can I keep my EXIF data?** Set `metadata` to `keep`. The orientation tag is reset, because the pixels are already rotated.

# Actor input Schema

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

Direct links to PNG, JPG, WEBP, GIF (first frame), BMP or TIFF files. One output file per image. Share/preview pages (Google Drive viewer, Dropbox ?dl=0) are not images - use the direct download link.

## `uploadedImage` (type: `string`):

Upload a single image from your computer (stored in a key-value store).

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

Pick one of your key-value stores that holds the images (read-only access). Every key ending in .png/.jpg/.jpeg/.webp/.gif/.bmp/.tif(f) is processed unless you list keys below.

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

Optional: only process these keys.

## `preset` (type: `string`):

Platform size to produce. Pixel sizes come from each platform's help pages (see README).

## `fitMode` (type: `string`):

How the design is placed when its aspect ratio differs from the target.

## `anchor` (type: `string`):

Where the design sits (contain) or which part is kept (cover). Many apparel sellers align designs to the top.

## `trimTransparent` (type: `boolean`):

Crop empty transparent borders before fitting so the design fills the print area. Default: on for apparel/sticker presets, off for others.

## `kdpTrimSize` (type: `string`):

Width x height in inches, e.g. 5x8, 5.5x8.5, 6x9, 8.5x11.

## `kdpPageCount` (type: `integer`):

Used for spine width (KDP: 24-830 pages).

## `kdpPaperType` (type: `string`):

Sets spine thickness per page (white/standard colour 0.002252 in, cream 0.0025 in, premium colour 0.002347 in).

## `kdpCoverType` (type: `string`):

Full wrap = 0.125 + trim + spine + trim + 0.125 inches wide. Hardcover is not supported (use KDP's template).

## `width` (type: `integer`):

Output width in pixels (preset "custom").

## `height` (type: `integer`):

Output height in pixels (preset "custom").

## `widthInches` (type: `string`):

Alternative to pixels: inches x DPI.

## `heightInches` (type: `string`):

Output height in inches (preset "custom"), multiplied by DPI.

## `scaleFactor` (type: `string`):

For preset 'scale': 1-8.

## `dpi` (type: `integer`):

DPI written into the file (and used to convert inches). Default: the preset's DPI (300, TeePublic 150).

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

File type. KDP covers must be PDF; Merch/Redbubble need PNG for transparency.

## `maxFileSizeMB` (type: `integer`):

Compress until the file fits (Merch preset defaults to its 25 MB limit). PNG: max compression, then optional 256-colour reduction. JPG/PDF: highest quality that fits.

## `allowColorReduction` (type: `boolean`):

Last resort when a PNG is still over the size limit: reduce to 256 colours with dithering (fine for most flat designs; may band smooth gradients). Off = fail instead (not charged).

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

Used to fill transparency/padding when the output has no alpha.

## `metadata` (type: `string`):

Strip removes camera/editor metadata (recommended for marketplace uploads). DPI and the sRGB profile are always written.

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

Real-ESRGAN network used for AI upscaling (both BSD-3-Clause, commercial use OK).

## `alphaUpscaling` (type: `string`):

How transparent edges are enlarged.

## `animatedImages` (type: `string`):

Animated GIF/WEBP/APNG: reject (default, not charged) or use the first frame.

## `maxImages` (type: `integer`):

Safety cap on images processed per run.

## `maxInputFileSizeMB` (type: `integer`):

Larger downloads are rejected (not charged).

## Actor input object example

```json
{
  "imageUrls": [
    "https://images-assets.nasa.gov/image/KSC-20170504-PH_SWW01_0006/KSC-20170504-PH_SWW01_0006~small.jpg"
  ],
  "preset": "merch-standard",
  "fitMode": "contain",
  "anchor": "center",
  "kdpTrimSize": "6x9",
  "kdpPageCount": 120,
  "kdpPaperType": "white",
  "kdpCoverType": "full-wrap",
  "scaleFactor": "4",
  "outputFormat": "auto",
  "allowColorReduction": true,
  "backgroundColor": "#FFFFFF",
  "metadata": "strip",
  "model": "general",
  "alphaUpscaling": "ai",
  "animatedImages": "reject",
  "maxImages": 100,
  "maxInputFileSizeMB": 50
}
```

# Actor output Schema

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

One row per image: status, download URL, size in px and inches, DPI, file size, warnings. Failed images are listed with the reason and are not charged.

## `files` (type: `string`):

All generated PNG/JPG/PDF files (key-value store).

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

Succeeded/failed counts, runtime, peak memory.

# 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/KSC-20170504-PH_SWW01_0006/KSC-20170504-PH_SWW01_0006~small.jpg"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("vncntlabs/print-ready-upscaler").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/KSC-20170504-PH_SWW01_0006/KSC-20170504-PH_SWW01_0006~small.jpg"] }

# Run the Actor and wait for it to finish
run = client.actor("vncntlabs/print-ready-upscaler").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/KSC-20170504-PH_SWW01_0006/KSC-20170504-PH_SWW01_0006~small.jpg"
  ]
}' |
apify call vncntlabs/print-ready-upscaler --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,vncntlabs/print-ready-upscaler"
        }
    }
}
```

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/FJZbYftw9b8AByGnW/builds/FQHQnjPn2KmcU6CcE/openapi.json
