AI Image Upscaler 2x/4x – Enhance Low-Res Photos (CPU)
Pricing
from $8.00 / 1,000 upscaled images
AI Image Upscaler 2x/4x – Enhance Low-Res Photos (CPU)
Upscale low-res photos 2x or 4x with an AI super-resolution network, on CPU. Pay per image, JPG/PNG/WebP in and out, photo and anime models, up to 8K.
Pricing
from $8.00 / 1,000 upscaled images
Rating
0.0
(0)
Developer
Francesco Antonio Russo
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
12 days ago
Last modified
Categories
Security
Limited permissionsShare
Make small, soft or JPEG-damaged pictures 2x or 4x bigger, sharper and cleaner, in bulk, with an AI super-resolution network that runs on plain CPU. Give a list of image URLs (JPG, PNG, WebP) or a dataset; get back one enlarged file per image (PNG, JPG or WebP) with a direct link, plus a row with the sizes, the time and the status.
All-inclusive price, no platform-usage surcharge: $0.008 per upscaled image ($8 per 1,000) for sources up to about 1 MP, and $0.03 ($30 per 1,000) for larger sources up to about 4 MP, a 1920 x 1080 frame included. You pay only for an image that was enlarged and stored, and only one of the two prices for each. Every model and scale has a stated size cap for each price (see "Limits"). Unreachable links, files that are not images, images over the largest cap, duplicates and errors are free, and the row tells you which model and scale would take the image. Set allowLarge to false if you want only the lower price.
It is a restoration network, not a generative one (read "What it does not do"). Weights are published under CC BY 4.0 with the author credited below; the exact files are checked by SHA-256 when the Actor is built.
What you get
- 2x or 4x enlargement. How big a source image can be depends on the model and the scale (table in "Limits"): for example a 1920 x 1080 frame goes to 3840 x 2160 at 2x or 7680 x 4320 at 4x with the
photomodel. - Two models:
photo(photographs and anything realistic; it also cleans JPEG blocking and mild noise; 2x and 4x) andanime(anime frames, cartoons, flat-colour illustrations; 2x only:animewith4xis refused when the run starts, free, with a message that names the combinations that exist). - Output as PNG (lossless), JPG or WebP with a quality setting. Transparency is kept in PNG and WebP (the alpha channel is enlarged separately, so edges stay clean) and flattened onto white in JPG.
- Tiling: big images are cut into tiles with mirrored context around each one and put back together, so memory stays under 1 GB and seams are not visible (a test compares tiled and untiled results on the real networks).
- Every file has a stable name (
00001_name_4x.png) and a direct link in the dataset row (resultUrl). - EXIF rotation is applied; GPS and other metadata are not copied into the results.
- Free rows, never a surprise: duplicates (same URL or the same file under another URL), dead links, HTML pages, GIF/TIFF/animated files, too-small and over-the-limit images all come back as a row with a
reasonand cost nothing. - Spending-limit aware (it stops before an image it could not charge) and safe after a platform migration (a restarted run neither repeats nor re-charges what was delivered).
- No browser, no GPU, no external API: the network runs inside the Actor.
Who it is for
- Online shops and marketplaces with supplier photos that are too small for the product page.
- Print-on-demand and photo-print services that need more pixels before printing.
- Archive, real-estate, news and media teams with old, low-resolution or heavily compressed images.
- Developers who want an upscaling step in a pipeline: URLs in, enlarged files and JSON out.
- Designers and illustrators with anime, game or cartoon art.
What it does not do (please read)
- It is not a diffusion or "creative" upscaler. It sharpens, removes compression blocking and rebuilds plausible fine texture; it does not invent a face, text or a logo that is not in the source. A heavily blurred or tiny face stays a blurred face, only cleaner. Do not use it as evidence or for forensic work: pixels it adds are an estimate.
- It can smear flat, noisy areas (sky, fur, plain walls at 4x can get a painted or streaked look). If a 4x result looks over-processed, try 2x: the network has less to guess.
- Text and thin line art are improved but not guaranteed to be legible when the source is too small to read.
- It does not colour-correct, denoise strongly, remove watermarks or change the picture. Animated images (GIF, animated WebP) are not supported.
- It is not Real-ESRGAN. That popular network's weights have no written licence of their own (see "Models and licence"); this Actor uses weights whose licence is written down.
- Images behind a login, a paywall or a private network cannot be fetched (the Actor only fetches the public internet).
How to use
- Paste image URLs in Image URLs, one per line, or point Dataset ID at a dataset that has them (the field
url,imageUrl,srcorimageis found automatically; set URL field for another name). - Choose Scale (2x or 4x), Model and Output format.
- Run. Open the Results view: each row has the preview, the sizes and the link. The files are also in the run's Key-value store.
The default input is a working example (two public Wikimedia Commons pictures at 4x).
Input
| Field | Meaning |
|---|---|
imageUrls | List of direct image links (up to 50,000 here; use a dataset for more). |
datasetId, urlField | A dataset whose rows hold image URLs, read after the list. A field with a list of URLs is expanded. |
scale | "2x" (default) or "4x". |
model | "photo" (default) or "anime" (2x only). |
outputFormat | "png" (default), "jpg" or "webp". |
quality | 1-100 for JPG and WebP, default 92 (WebP 100 is lossless). Ignored for PNG. |
allowLarge | true (default): sources above the standard size are enlarged too, at the image-large price. false: only the standard sizes, at the lower price; bigger images are free skipped rows. |
maxImages | Stop after this many images were enlarged. |
Output
One row per input image in the dataset, the enlarged files in the key-value store, and a SUMMARY record. Example row (real run):
{"inputIndex": 0,"sourceUrl": "https://upload.wikimedia.org/wikipedia/commons/thumb/9/9a/Gull_portrait_ca_usa.jpg/960px-Gull_portrait_ca_usa.jpg","status": "upscaled","reason": null,"model": "photo","scale": 4,"outputFormat": "jpg","inputWidth": 960,"inputHeight": 720,"outputWidth": 3840,"outputHeight": 2880,"tiles": 30,"resultKey": "00001_Gull_portrait_ca_usa_4x.jpg","resultUrl": "https://api.apify.com/v2/key-value-stores/<STORE_ID>/records/00001_Gull_portrait_ca_usa_4x.jpg"}
Reasons for a free row
| Reason | Meaning |
|---|---|
invalid-url | The entry is not text, not an http(s) URL, or has a user name or password in it. |
blocked-address | The host resolves to a private or reserved address (localhost, internal networks): the Actor only fetches the public internet. |
unreachable | The server did not answer, answered an error (404, 403, 5xx...), redirected too many times, or took longer than 45 seconds. |
not-an-image | The download is not an image (an HTML page, an empty file, a broken file). |
unsupported-format | A format other than JPG, PNG or WebP (GIF, TIFF, AVIF, SVG...) or an animated image. |
too-small | The shortest side is under 16 pixels. |
too-large | The file is over 40 MB, or the source is bigger than the model and scale you chose accept (the cap is in megapixels, see Limits; the message names the combinations that fit), or a side would pass 16,383 pixels in the result. |
duplicate | The same URL, or a different URL with the identical file, as an earlier row. |
error | An unexpected error while processing. Please report it with the run ID; it is not charged. |
The SUMMARY record
status (finished, partial, failed or invalid-input), stopReason, totals (items, upscaled, skipped, failed, resumed, billable), skippedByReason, performance (megapixels, processing seconds, seconds per input megapixel, peak memory, threads), the model with its SHA-256 and licence, and the number of charges made.
Price
Pay per event, two events (platform usage is included in both prices):
| Event | When | Price | Per 1,000 |
|---|---|---|---|
image ("Upscaled image") | the source is up to the standard cap of its model and scale (photo 1 MP at 2x, 0.9 MP at 4x; anime 0.6 MP) | $0.008 | $8 |
image-large ("Upscaled large image") | the source is above that cap, up to the large cap (photo 3.9 MP at 2x, 2.12 MP at 4x; anime 2.4 MP), a 1920 x 1080 frame included | $0.03 | $30 |
Each upscaled image is charged one of the two events, never both; the dataset row says which one (chargedEvent) and the SUMMARY counts both.
| Images upscaled | Cost at image | Cost at image-large |
|---|---|---|
| 100 | $0.80 | $3.00 |
| 1,000 | $8.00 | $30.00 |
| 10,000 | $80.00 | $300.00 |
The price does not change with the output size or the scale, only with the size of the source image. Set allowLarge to false to pay only the lower price (bigger images are then free skipped rows). Free: unreachable URLs, files that are not images, unsupported formats, images that are too small or over the largest cap of the model and scale, duplicates (same URL or same content), non-text entries and processing errors. The row is stored and the result saved first, then the charge is made, one image at a time: an image whose result could not be stored is never charged. Set the maximum cost per run in the run options for a hard cap: the Actor reads it and stops before an image it could not charge.
Speed and memory (measured)
On the Apify platform CPU follows memory: 4,096 MB gets one CPU core (Apify documentation), plus a short start-up boost that does not last. So the speed that counts for a batch is the sustained one, and that is what the table gives: measured on 22 October 2026 with memory 4,096 MB and one thread, as the median of images 3 to 8 of a batch of 8 (the first images of a run are faster than the rest and are not counted). The time is decode + network + encode; the download is separate. Peak memory stayed under 0.8 GB at every size.
| Model | Scale | Sustained speed, seconds per input MP | Time at the largest standard size | Time at the largest large size |
|---|---|---|---|---|
photo | 2x | 18.9 (measured at 2.46 MP) | 18.9 s | 73.7 s |
photo | 4x | 21.0 (measured at 1.39 MP) | 18.9 s | 44.6 s |
anime | 2x | 31.0 (measured at 1.84 MP) | 18.6 s | 74.4 s |
Count with these numbers, not with the first image of a run: for example 1,000 photo 2x images of 1 MP take about 5 hours in one run (the Actor processes one image at a time; start several runs to go faster). There is no anime 4x: the network we tried for it was about 10 times slower than photo 4x (205 against 21 seconds per megapixel), which would have limited it to sources of about 340 x 260 pixels, so it is not offered. For a 4x enlargement of anime art use photo 4x (try it on a sample) or anime 2x.
The default memory is 4,096 MB and it is also the minimum: below it the run gets less than one core. Apify gives proportionally more cores to more memory and the Actor then uses them, but we have measured only 4,096 MB: the table and the limits are for that setting.
Limits
The largest source image depends on the model, the scale and the price: each cap is set from the sustained speed in "Speed and memory", so that an image never takes longer than its price pays for. The photo 4x large cap is the 34-megapixel limit of the result (2.12 MP of source), not the speed.
| Model | Scale | Standard price (event image): source up to | Large price (event image-large): source up to | Example at the large size (4:3) |
|---|---|---|---|---|
photo | 2x | 1 MP | 3.9 MP | 2280 x 1710 to 4560 x 3420 |
photo | 4x | 0.9 MP | 2.12 MP | 1680 x 1260 to 6720 x 5040 |
anime | 2x | 0.6 MP | 2.4 MP | 1780 x 1340 to 3560 x 2680 |
| Value | |
|---|---|
| Longest side of the result | 16,383 px (the WebP format cannot go further) |
| Shortest source side | 16 px |
| File size | 40 MB |
| URLs typed in the input | 50,000 (use a dataset for more) |
An image over the cap is a free row: status: "skipped", reason: "too-large", and a message with its size, the cap, the model and scale combinations that would take it, and a size to shrink it to. Nothing is charged and nothing is enlarged. Other free rows say what to do too (send JPG, PNG or WebP). Downloads time out after 45 seconds; 429 and 5xx answers are retried; at most 5 redirects are followed.
Models and licence
You choose a model with model; the Actor loads the file for the scale you asked.
| Option | Scale | Network | File (SHA-256) | Release |
|---|---|---|---|---|
photo | 2x | SPAN | 2xNomosUni_span_multijpg_fp32_opset17.onnx4c088922fcb40584a95a1b98009e3042a61ada46f237a9e72e8a2ed127832004 | 2xNomosUni_span_multijpg |
photo | 4x | SPAN | 4xNomosUni_span_multijpg_fp32_opset17.onnxa435b009109e72c50ce95927dab0a6dde63e594cf57ba5a18ba63da67355698a | 4xNomosUni_span_multijpg |
anime | 2x | SRVGGNetCompact | 2xHFA2kCompact_fp32_opset17.onnxeef4f756cebad996c95d11aa863cba0d70174ec2865f87d5b1bb5cc69578ff3c | 2xHFA2kCompact |
Model weights by Philip Hofmann (Phhofm), from https://github.com/Phhofm/models, licensed under CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/). The files are used exactly as published (not modified, not re-trained).
- Each release page states "License: CC BY 4.0", which allows commercial use and redistribution with attribution. The files are ONNX conversions published by the author himself; this Actor downloads them from his GitHub releases when it is built, checks size and SHA-256, and uses them without any change (no re-training, no merging).
- CC BY 4.0 requires credit: the author and the licence are named here, in every run's
SUMMARY.model, and in the log of every run. - Why not Real-ESRGAN? Its code is BSD-3-Clause, but the pre-trained weights have no licence statement of their own, the questions about commercial use of the weights (xinntao/Real-ESRGAN issues #677, #1015, #1016) were still unanswered on 22 October 2026, and the training data of that family (DIV2K, OST) comes with research-only terms. We preferred weights with a written commercial licence.
- 🔶 What we cannot verify: the author does not publish a licence for the training images of these networks. The licence of the weights is what he states.
Privacy
- The Actor fetches only the URLs you give it and sends nothing to third parties; the network runs locally.
- The query string of a URL (signed links) never goes to the log; the dataset row keeps the URL exactly as you gave it.
- URLs that point to a private or reserved address (localhost, internal networks) are refused, also after a redirect.
- Result files are in the run's key-value store. Anyone who has the link can open a file (as for every record of a run); the store is deleted after your plan's retention period. Download what you want to keep.
- Metadata of your pictures (EXIF, GPS, colour profile) is not copied into the results.
How resume and the spending limit work
- Resume: if the platform migrates the run, the new instance reads the rows already in the dataset (by
inputIndex) and continues; those images are not downloaded, enlarged or charged again. If the old instance died between storing a row and charging it, the missing charge is made once, at restart. - Spending limit: before each image the Actor asks how many more
imagecharges the limit allows, and for a large image how manyimage-largecharges; when none, it stops and the SUMMARY says so. Free rows do not use the budget. - Guard: if the price list of the Actor has no
imageevent the run refuses to start, so it can never run without a cost limit. If it has noimage-largeevent, large images are skipped (free) with a warning instead of being charged at an unlisted price.
Use it from code
curl -X POST "https://api.apify.com/v2/acts/<USERNAME>~ai-image-upscaler-2x-4x/run-sync-get-dataset-items?token=<YOUR_TOKEN>" \-H "Content-Type: application/json" \-d '{"imageUrls": ["https://example.com/small.jpg"], "scale": "4x", "model": "photo", "outputFormat": "webp", "quality": 90}'
from apify_client import ApifyClientclient = ApifyClient("<YOUR_TOKEN>")run = client.actor("<USERNAME>/ai-image-upscaler-2x-4x").call(run_input={"imageUrls": ["https://example.com/small.jpg"],"scale": "2x","outputFormat": "png",})for row in client.dataset(run["defaultDatasetId"]).iterate_items():print(row["status"], row["resultUrl"])
FAQ
Will a 4x result look like a real 4x photo? It will look cleaner and sharper than a plain resize, and fine texture is rebuilt, but it is an estimate. The best results come from sources that are small but not blurred beyond recognition. When in doubt, compare 2x and 4x.
Which model for a product photo with a white background? photo. For logos and flat graphics try both: anime suits flat colours and hard edges.
Why is my image "too-large"? Each model and scale has a largest source size (table in "Limits"): photo 2x 1 MP, photo 4x 0.9 MP, anime 2x 0.6 MP at the standard price, and with allowLarge (default) up to 3.9 MP, 2.12 MP and 2.4 MP at the image-large price (anime has no 4x). The row's message names the combinations that take your image. Or shrink the image first.
Can it read images that need a login? No. It fetches public URLs only.
Do I pay for a duplicate or a failed download? No. Only status: "upscaled" rows are charged.
Is the result safe to use commercially? The weights are CC BY 4.0 (commercial use allowed with credit to the author, already given in the Actor output). The rights to your pictures are yours to check.
Does it keep EXIF or colour profiles? No; results are plain sRGB without metadata.
A run was interrupted. Am I charged twice? No (see "How resume and the spending limit work").