QR Code Tools

How to Make a QR Code That Always Scans: Size, Contrast and Error Correction

We generated QR codes, covered them with logos, lowered the contrast, shrank them and removed the margin, then tried to decode them. Here is what makes a QR code reliable and what quietly breaks it.

By Published Updated 6 min read

A QR code on a flyer, a menu or a parcel has one job: to open the right thing the moment someone points a phone at it. When it fails, people rarely try twice. Most failures come from a handful of design decisions, and you can test all of them before printing. We generated codes with the same library our QR Code Generator uses and tried to read them with two open-source decoders, ZBar 0.23 and OpenCV 5.0.

How a QR code stores data

The QR code was developed by Denso Wave in Japan in 1994 and is standardized as ISO/IEC 18004 (latest edition 2024). It is made of small squares called modules. The smallest version has 21 × 21 modules; each of the 40 versions adds four modules per side, up to 177 × 177. The three large squares in the corners tell the scanner where the code is and how it is rotated.

Part of every code is redundancy (Reed–Solomon error correction), so a damaged or dirty code can still be read. You choose how much:

LevelData that can be restoredTypical use
Labout 7%Clean screens, very long content
Mabout 15%The usual default for print and screens
Qabout 25%Outdoor use, rough or curved surfaces
Habout 30%Codes with a logo, harsh conditions

The standard also requires a quiet zone: a blank margin four modules wide around the code. As our tests show, it matters more than it looks.

Longer content means denser codes

The more characters you encode and the more error correction you choose, the more modules the code needs. We encoded four typical contents:

Modules per side, without the quiet zone. Generated with the qrcode-generator library that our tool uses (automatic version, byte mode).
ContentCharactersLMQH
Homepage URL (https://omid57.eu/)1825252529
Page URL (…/en-US/tools/qr-code-generator)4729333741
The same URL with four UTM tracking parameters12841495361
Wi-Fi login (network name and password)5433333741

The tracking parameters pushed the code at level M from 33 to 49 modules per side. Printed at the same size, every module becomes about 28% smaller, because the width is shared by 57 instead of 41 module widths (quiet zone included). A short URL is the easiest way to a robust code.

How big does a QR code need to be?

What decides whether a code scans is how many camera pixels each module covers. We shrank codes until each module was a given number of pixels wide, blurred them slightly like a camera lens, and tried to decode them:

Image reduced with area averaging, then a 1-pixel Gaussian blur.
Pixels per module25 × 25 code33 × 33 code49 × 49 code
2not readnot readnot read
2.5ZBar onlynot readZBar only
3read by bothread by bothread by both
4read by bothread by bothread by both

Both decoders needed about three pixels per module. For the person scanning, that means: if the modules are twice as big, the code can be read from twice as far away, and a denser code must be scanned from closer. You can calculate the module size of your print:

module size = printed width ÷ (modules per side + 8)

3 cm wide, 33 × 33 code:  30 mm ÷ 41 ≈ 0.73 mm
3 cm wide, 49 × 49 code:  30 mm ÷ 57 ≈ 0.53 mm

Whatever size you choose, print a proof and scan it from the distance at which people will actually stand, for example across a table or from the pavement in front of a shop window.

Logos: how much can you cover?

Error correction lets a code survive damage, which is why many designs place a logo in the middle. We covered the center of the 47-character URL code with a blank square of increasing size and checked when decoding failed:

Both decoders, unless stated otherwise. Above these values, both failed.
LevelRestorable dataLargest center area that still scanned
Labout 7%3% of the code area
Mabout 15%7%
Qabout 25%12% (OpenCV: 15%)
Habout 30%18%

In practice you can cover only about half to two thirds of the nominal percentage: a logo also cuts codewords partly, and the nominal value is the best case. If you add a logo, choose level H, keep the logo well below 15% of the area and never touch the three corner squares. Our generator does not add logos; if you place one in an image editor, generate the code at level H and test the result.

Contrast and color

On clean digital images, both decoders read even very pale codes. Photos taken by a camera are different, so we added sensor noise, a slight blur and light falling to 65% across the code, and ran each test ten times:

Contrast = how much darker the modules are than the background.
Grey value of the dark modulesContrast to the white backgroundZBarOpenCV
0 (black)100%10 of 108 of 10
6475%10 of 1010 of 10
9662%7 of 107 of 10
12850%1 of 109 of 10
16037%0 of 109 of 10
19225%0 of 100 of 10

Keep the dark modules really dark: around 75% darker than the background was reliable for both decoders. What counts is brightness, not color. Navy or black on white is ideal; pure red on white is only about 66% darker and already borderline; light blue (about 33%) and yellow (about 21%) on white are not suitable.

The quiet zone is not optional

We placed codes on a busy black-and-white pattern, with a blank margin of 0, 1, 2 or 4 modules, on ten different random backgrounds each:

Quiet zoneZBarOpenCV
0 modules8 of 100 of 10
1 module10 of 1010 of 10
2 modules10 of 109 of 10
4 modules (standard)10 of 1010 of 10

Without any margin, OpenCV failed every time. Our generator always adds the standard four-module margin. Don’t crop it away in your layout, and keep text, photos and patterns out of it.

Static codes never expire

Our generator creates static codes: the content itself, such as the URL, the Wi-Fi details or the email address, is stored in the pattern, so the code works forever without any service behind it. So-called dynamic codes from some providers contain only a short link to the provider, which then forwards visitors; if the subscription ends, every printed code stops working. For printed material, a static code that points to an address on your own domain gives you both: it never expires, and you can change where it leads with a redirect on your website.

Security: scan with care

Nobody can read a QR code with their eyes, which makes it ideal for hiding a harmful link. In December 2023 the US Federal Trade Commission warned that scammers stick their own codes over real ones, for example on parking meters, and send codes by email or text message with urgent requests. Before you open a scanned link, check the address your phone shows; don’t scan codes from unexpected messages; and check from time to time that nobody has covered your own printed codes with a sticker.

QR Code GeneratorCreate QR codes for links, text, Wi-Fi and email. Choose colors and error correction, and download as PNG or SVG. Free, no sign-up, no tracking.Open tool

Checklist before printing

  • The content is as short as possible, with no unnecessary tracking parameters.
  • Level M for normal use; Q or H outdoors, on curved or rough surfaces or with a logo.
  • Dark modules on a light background with strong contrast, never inverted.
  • The four-module quiet zone is complete and free of text and graphics.
  • SVG for print, because it scales without blurring; PNG for screens and documents.
  • A short line of text next to the code says where it leads, for example “Menu: example.com/menu”.
  • The proof has been tested with at least two different phones at the real distance and in the real light.

Tools used in this guide

Frequently asked questions

Which error correction level should I choose?

Level M suits most codes on paper and screens. Choose Q or H for codes outdoors, on curved or rough surfaces or with a logo, and L only for very long content shown on a screen.

Do QR codes expire?

Static codes, like the ones our generator creates, never expire because the content is stored in the code itself. Dynamic codes from some services depend on that service and stop working when it is discontinued or the subscription ends.

Can I put a logo in the middle of a QR code?

Yes, with level H. In our test, a blank area of up to 18% of the code still scanned at level H, but only 7% at level M. Keep the logo well below 15%, leave the corner squares untouched and test the printed result.

Why doesn’t my QR code scan?

The most common causes are a code that is too small or too dense for the distance, low contrast, inverted colors, a missing quiet zone, reflections on glossy material and curved surfaces such as bottles.

Is a Wi-Fi password in a QR code safe?

The password is stored as plain text in the code, so anyone who scans or photographs it can read it. Use Wi-Fi codes for guest networks and change the password when necessary.

Is my data sent anywhere when I create a code?

No. Our QR code generator creates the code in your browser; the content you enter is not sent to our server.

Sources and further reading

  1. ISO/IEC 18004:2024 – QR Code bar code symbology specification (www.iso.org)
  2. KEYENCE: What is a QR code? (versions, error correction, quiet zone) (www.keyence.com)
  3. CNBC: QR codes may be a gateway to identity theft, FTC warns (December 2023) (www.cnbc.com)
All guides