# QR code pixelated when enlarged

> Enlarging a raster QR code cannot add detail. Bicubic and bilinear resampling blur module edges into gradients; nearest-neighbour keeps edges sharp but distorts module widths at non-integer scales. The only correct fix is regenerating the code at the size you need, or exporting SVG, which scales to any size with perfect edges.

Source: https://useqr.app/docs/troubleshooting/qr-code-pixelated-when-enlarged · Last reviewed 2026-08-21 · UseQR is free forever, no signup.

---

## Why enlargement cannot work

A raster image contains a fixed amount of information. Scaling it up does not add detail. It invents pixels by guessing from the neighbours. For photographs the guesses look fine. For a QR code, whose entire meaning lives in the exact position of hard dark-light edges, the guesses are the damage.

## The counterintuitive part: "smooth" scaling is the worst

Bicubic and bilinear resampling (the defaults in nearly every image editor) are designed to make photos look natural by blending across edges. That blending is precisely what a QR code cannot afford. Each module boundary becomes a gradient, and when a decoder later thresholds the image to pure dark and light, gradient pixels sit at the threshold where noise, lighting and printing decide which way they flip. A "smoothly" enlarged code often looks better to the eye and scans worse than a blocky one.

## Nearest-neighbour is only safe at integer multiples

Nearest-neighbour resampling keeps edges hard, so it seems like the right tool. It is, but only at exact **integer multiples** (2×, 3×, 4×), where every source pixel becomes a clean block. At a non-integer factor such as 2.4×, rounding forces some modules to come out 2 pixels wide and others 3, a **50% width difference between modules that should be identical**. That distortion lands directly on the [timing pattern](/glossary/timing-pattern) and module grid the decoder uses to map the symbol.

## The right fixes

1. **Regenerate at the size you need.** A QR code is computed from its payload, so a fresh render at 2,048 px costs nothing and is pixel-perfect. With our API it is one parameter: `https://useqr.app/api/v1/qr?data=hello&size=2048`.
2. **Export SVG once and never think about size again.** Vector output renders exactly at any dimension: the case is laid out in [vector vs raster QR codes](/docs/spec/vector-vs-raster-qr-codes), and [making a high-resolution QR code](/docs/how-to/how-to-make-a-high-resolution-qr-code) walks through both routes.
3. **Lost the original data?** Decode the small image with our [scanner](/scan) to recover the exact payload, then regenerate clean. Never ship an upscaled rescue.

## If it must stay on screen

For web embeds, an SVG sized with CSS is the clean answer. If you are stuck with a small PNG, `image-rendering: pixelated` at an exact integer device-pixel multiple avoids browser smoothing, but this is a patch, not a fix, and it breaks the moment a user zooms.

Whatever route you take, run the final artwork through the [validator](/validate). It decodes the rendered result, which is the only test that matters.

## FAQ

### How do I enlarge a QR code without losing quality?
You do not enlarge it: you regenerate it. A QR code is computed from its data, so rendering a fresh copy at the target size, or exporting SVG, produces perfect edges at any dimension in seconds.

### Why does my enlarged QR code look sharp but not scan?
Nearest-neighbour enlargement at a non-integer factor keeps edges hard but makes identical modules different widths. The decoder's grid mapping depends on consistent module size, so the code looks crisp and still fails.

### Is SVG always better than PNG for QR codes?
For anything that will be resized or printed, yes: vector edges are exact at every size. PNG is fine when generated at the exact display or print size and never scaled afterwards.

### Can AI upscalers fix a low-resolution QR code?
They make it look nicer, not decode better, and a hallucinated module is a changed module. Decode the original to recover the payload, then regenerate. If the original no longer decodes, no upscaler will recover data that is not there.

## Try it

- https://useqr.app/validate
- https://useqr.app/scan
