How the 4K image upscaler works
Everything happens on your own device: your browser reads the image, your graphics chip enlarges and sharpens it, and the result is saved to a file you download. No part of the image is sent to a server.
In plain language
A normal resize spreads each pixel over a larger area, which blurs edges. 4K Images looks at the direction of edges in the image and enlarges along them, so lines and outlines stay crisp. It then sharpens where there is real contrast and leaves smooth areas such as skies and skin alone, so noise is not amplified.
Optional cleanup smooths sensor noise and the blocky artifacts of heavily compressed JPEGs while keeping edges intact. It helps most with phone photos and images saved at low quality.
What it does not do: it does not invent or restore detail that is not in the original. A blurry or very small photo becomes larger and cleaner, not more detailed. There is no AI model involved.
The technical pipeline
Each image is processed in a Web Worker, off the page's main thread, so the page stays responsive.
-
Decode
The browser decodes the file with createImageBitmap, applying the EXIF orientation so photos come out the right way up. The engine notes whether the image has transparency.
-
Optional cleanup
The engine first measures how noisy the image is, then scales the filter to it, so clean images keep their fine texture. Low runs an edge-preserving bilateral filter (5×5); High uses a 7×7 bilateral filter plus a deblocking pass on the 8×8 JPEG block grid. Both are WebGL2 fragment shaders. Off skips this step.
-
Edge-adaptive upscaling
EASU (Edge-Adaptive Spatial Upsampling) from AMD FidelityFX Super Resolution 1 enlarges the image in passes of at most 2×, and the last pass lands exactly on the target size. Large images are processed in overlapping tiles so graphics memory limits are never exceeded. Without WebGL2, the engine falls back to a Lanczos3 resize (pica).
-
Sharpening
RCAS (Robust Contrast-Adaptive Sharpening) runs after every enlargement pass, while edges are still narrow, and adds definition in proportion to local contrast. Its limiter prevents halos, and flat areas are left alone so they do not turn grainy. The Sharpness slider sets its strength; 0 turns it off. Without WebGL2, an unsharp mask with a threshold is used instead.
-
Optional auto contrast
Stretches brightness so the darkest 0.5% and brightest 0.5% of pixels reach the ends of the range, without shifting colours.
-
Encoding
The result is saved with codecs from the Squoosh project compiled to WebAssembly (via jSquash): MozJPEG, libwebp, libavif and OxiPNG. Only the codec for the format you pick is downloaded.
Open-source credits
- AMD FidelityFX Super Resolution 1 (EASU, RCAS) MIT
- jSquash (MozJPEG, libwebp, libavif, OxiPNG) Apache-2.0; codecs under BSD, IJG and MIT licences
- pica MIT
- fflate MIT
- Inter and JetBrains Mono typefaces SIL Open Font License 1.1
Full licence texts: third-party notices.