AI-powered image upscaler for large-format canvas prints. Takes any photo or illustration and upscales it to an exact print target (e.g. 24×36 inches at 150 DPI) using Real-ESRGAN on the GPU, with optional Claude judgment steps for classification, artifact QA, and fit/crop advice.
- NVIDIA GPU with CUDA (tested: RTX 3090, CUDA 12.1). CPU mode is not supported.
- Python 3.11+
# Install PyTorch with CUDA 12.1 first (required before the package):
pip install torch==2.1.2 torchvision==0.16.2 --index-url https://download.pytorch.org/whl/cu121
# Then install superscale:
pip install -e .Model weights (Real-ESRGAN, GFPGAN) are downloaded automatically on first run.
superscale photo.jpg --print 24x36@150Produces photo_superscaled.tiff at 3600×5400 px with DPI metadata set to 150.
superscale photo.jpg --print 24x36@150 --out output.tiff --format tiffSupported formats: tiff (default), png, jpeg.
superscale photo.jpg --print 24x36@150 --no-claudeBypasses all three Claude judgment steps. Uses RealESRGAN_x4plus (photo
model), pad fit, and assumes QA is clean. Useful for batch runs or when the
Claude CLI is unavailable.
# Letterbox/pillarbox (black bars): preserve full image
superscale photo.jpg --print 24x36@150 --fit pad
# Center-crop to fill frame exactly
superscale photo.jpg --print 24x36@150 --fit crop
# Let Claude recommend crop vs pad based on composition (default)
superscale photo.jpg --print 24x36@150 --fit auto# Allow up to 4 total upscale attempts (1 initial + 3 retries)
superscale photo.jpg --print 24x36@150 --max-retries 3
# Single attempt only (no retries)
superscale photo.jpg --print 24x36@150 --max-retries 0--max-retries is the number of RETRIES, not the total attempt count.
Total attempts = --max-retries + 1. Default is 2 (up to 3 total attempts).
# 11×17 at 300 DPI
superscale photo.jpg --print 11x17@300The --print spec format is WxH@DPI where W and H are in inches.
Claude views the source image and returns {"type": "photo|illustration|anime", "faces": true|false}. The type selects the Real-ESRGAN model:
| Type | Model | Face enhance |
|---|---|---|
| photo | RealESRGAN_x4plus | if faces |
| anime/illustration | RealESRGAN_x4plus_anime_6B | no |
| other/fallback | realesr-general-x4v3 | if faces |
Fallback (no Claude or bad JSON): photo, no face enhancement.
Real-ESRGAN runs as many 4× passes as needed to reach or exceed the target pixel dimensions. An OOM backoff doubles the tile size on GPU memory errors and retries.
Claude compares 100% crops from five regions of the upscaled image against the
same crops from a Lanczos-rescaled version of the source. If artifacts or
over-smoothing are detected (verdict: artifacts), the pipeline retries with:
- Switch to
realesr-general-x4v3withdenoise=0.5 - Lower denoise to
0.25 - Lower denoise to
0.0
After all retries are exhausted the best result is exported anyway, with
qa_clean: False and a list of detected issues in the report.
Fallback (no Claude or bad JSON): verdict: ok, qa_clean: True.
Claude advises whether to pad or crop the upscaled image to the exact target canvas. The result is applied before export.
Fallback: pad (letterbox/pillarbox).
Output is saved as TIFF (default) with DPI metadata embedded via PIL. The report printed to stdout includes final pixel dimensions, achieved DPI, attempt count, models used, and QA verdict.
output: photo_superscaled.tiff
final: 3600x5400 @ ~150 dpi (24.0x36.0 in)
attempts: 1 models: RealESRGAN_x4plus
qa_clean: True
- Per-tile QA and retry: current QA examines five fixed crops of the full image; a tile-level loop would catch localized artifact pockets.
- Multi-panel split: automatic splitting into diptych/triptych panels for prints wider than a single canvas.
- Web UI: browser-based drag-and-drop frontend with live progress.
- Explicit sRGB ICC embedding: current export embeds DPI metadata via PIL but does not attach an ICC color profile. True sRGB ICC embedding is deferred.
- Gallery-wrap border: gallery_wrap_in is returned by the Claude print-prep step but the mirrored-edge extension is not yet wired into the main pipeline.
- Weights cache location: model weights download to the site-packages
weights/directory inside the virtualenv; a user-configurable XDG cache path is not yet supported.