The decode margin.

Verified October 2026

One budget, several spenders

A QR code carries redundancy: some of its codewords can be wrong or missing and the message still comes back. That redundancy is the decode margin, and it is one budget. A centre logo spends it, because the modules under the logo are gone; a photo woven through the pattern spends it; weak contrast and small print spend it too. The QR maker is built so that each cost is either computed and shown or stopped at a measured limit. This guide sets out those rules in the engine’s own terms, with figures computed on one fixed, fictional destination, https://example.com/spring-market. Verify against the standards’ own documentation before a critical print run or launch.

The budget comes from the error-correction level. The four levels tolerate ≈7% (L), ≈15% (M), ≈25% (Q) and ≈30% (H) erroneous codewords, as stated in the reference encoder the engine vendors (source, 2026-10-02). The engine encodes at level M unless another level is chosen; L, M, Q and H are selectable only when no logo is present. The level reported is never lower than the one requested but may be higher, because the reference encoder raises it whenever that does not increase the symbol version.

A logo forces level H, and the engine reports it

Encoded on its own, the example destination comes back as a version 3 symbol of 29×29 modules at level M. Encoded with a centre logo, the same text comes back at level H, version 4, 33×33 modules, with the flag ecForcedByLogo set to true. The engine’s header gives the reason: the logo destroys modules that error correction must reconstruct, so the choice is not left to the user.

The rule is locked twice: encoding with a logo forces H, and the renderer refuses a logo on any model encoded lower with “A logo overlay requires error correction level H. Re-encode with the logo option set.”

What level H costs: more modules in the same square

More codewords mean a denser symbol for the same text. The engine always draws a quiet zone of 4modules on every side, which nothing in the interface can disable; the public statement of the rule is DENSO WAVE’s: “QR Code requires a four-module wide margin at all sides of a symbol.” (source, 2026-10-02). With the quiet zone counted, the plain example is 37×37 modules and the logo version 41×41.

The extra modules are paid for in module size. At the smallest PNG preset, 512 pixels, which prints as 1.71 in × 1.71 in (43.3 mm × 43.3 mm) at 300 DPI, each module of the plain example is 1.17 mm wide and each module of the logo version 1.06 mm. At the same print size the logo version has smaller modules, so it needs more physical size than the plain code. Apply the distance rule in the QR sizing guide to the logo version.

How much a logo may cover: a measured cap

The engine caps the logo knockout at 16% of the symbol area, excluding the quiet zone, and requests 12%when no size is asked for. The knockout — the image plus its pad, everything that obscures modules — is what the cap applies to. The figure is measured, not derived: the engine’s note records that with a worst-case opaque dark logo on clean, undegraded rasters, the decoder fails at a 20% area on version 4 and version 6 symbols while 16% decodes. The ≈30% codeword recovery of level H does not translate into ≈30% of the area, because a centred knockout produces burst erasures that consume the margin much faster than scattered damage. The default is held below the cap so a real print, degraded by printing and scanning, keeps decode headroom.

At 8 pixels per module on the example logo model, the default knockout is 91.5 pixels on a side — 34.6% of the symbol side, the square root of the area fraction, or about 11.4 of the symbol’s 33 modules. The pad is one module on each side, leaving 75.5 pixels, about 9.4 modules, for the image.

Where the logo path stops, in the engine’s words:

  • Above the cap it refuses rather than clamps. Asking for 20% returns “A logo may cover at most 16% of the symbol area — above that, the code stops decoding even on a clean scan.”
  • The logo must be a data: URL image already in the browser; https://example.com/logo.png returns “The logo must be a data: URL image (PNG, JPEG, GIF, WebP, or SVG). Remote URLs are not supported.”

Photo-woven codes: what stays pure

The artistic styles — heart modules, the photo halftone and the framed composites — follow production rules the engine states as law. Error correction is H for every one of them, and each entry point rejects a model encoded lower. Finder and alignment patterns stay classic squares, because restyling them broke decoding outright in the engine’s decode spike; only timing modules may be styled.

The halftone splits each data cell into a three-by-three grid. The eight outer subcells show the photo quantised to three tones — dark below a luminance of 85, light above 175on the 0–255 scale, the mid tone between. The centre square, 50%of the cell side, is drawn last in the pure module colour and is, in the engine’s word, authoritative; the engine records that ratio as the measured floor, below which decoding fails. Finder, alignment and timing cells and the quiet zone stay fully pure.

The hardest limit is payload length. Photo weaving is decode-proven only up to version 4, because denser symbols shrink the authoritative centres below the decoder’s sampling viability; the engine’s character guidance from that cap is 34 ASCII characters, fewer with emoji or accents. The example destination at level H is version 4 and renders as a 41×41-module image, quiet zone included. A longer destination, https://example.com/events/spring-market/tickets?ref=flyer, is version 6at level H and is refused: “Photo-woven codes need short content — use a short link or pick another style. This content needs a version-6 code; photo weaving is decode-proven only up to version 4 (about 34 characters, fewer with emoji or accents).” That is why the tool page asks for a short link; how payload length sets the version is covered in how the QR maker encodes ten payload types.

The other styles spend less. Heart modules cover 0.97of their cell, a decode-verified figure, so a scanner’s sampling grid still reads each cell as decisively dark. The framed composites (heart, floral, ring, classic, confetti) never touch the code: the rendered QR markup is nested byte-for-byte on an opaque panel above the frame art.

Contrast: computed, warned about, or refused

The engine computes the WCAG 2.x relative-luminance contrast ratio of your foreground and background and warns below 4.5:1, the Level AA minimum for text, which WCAG states as “The visual presentation of text and images of text has a contrast ratio of at least 4.5:1, except for the following:” (source, 2026-10-02). Its note says why: scanners binarise the image, so contrast below that level measurably hurts decode rates.

On fixed pairs: black on white measures 21.00:1. A navy #1e3a8a on white measures 10.36:1 and passes. An amber #d97706 on a cream #fef3c7 measures 2.86:1 and returns “Low contrast (2.86:1). Scanners may fail below 4.5:1 — darken the foreground or lighten the background.”

Polarity is checked separately. White on the same navy measures the same 10.36:1, yet the engine flags it: “Light-on-dark (inverted) codes are not reliably read by all scanners. Prefer dark modules on a light background.”

The classic maker warns and leaves the decision to you, in line with the colour doctrine the methodology describes. The artistic engine refuses, because its decoration has already spent the margin: the amber-on-cream pair handed to the heart style returns “Artistic styles require at least 4.5:1 contrast (got 2.86:1) — decoration already spends decode margin.” and the inverted pair “Artistic styles require dark modules on a light background — inverted codes are rejected.”

Print size is arithmetic, and it includes the quiet zone

PNG export offers 3 pixel sizes; the readout under each is pixels divided by 300 dots per inch, with millimetres from inches:

  • 512 px → 1.71 in × 1.71 in (43.3 mm × 43.3 mm) at 300 DPI
  • 1024 px → 3.41 in × 3.41 in (86.7 mm × 86.7 mm) at 300 DPI
  • 2048 px → 6.83 in × 6.83 in (173.4 mm × 173.4 mm) at 300 DPI

The readout describes the whole image, quiet zone included, because the quiet zone is part of the exported pixels; divide by the total module count to learn how large each module prints. The SVG export has no pixel size and scales to any print size without quality loss, which is why the Studio’s package carries the code as PNG and SVG side by side (see the package anatomy guide).

Whether a size is enough is a question about viewing distance, not about the engine. The sizing guide’s close-range rule of thumb is at least 2×2 cm (0.8×0.8 in), a figure that keeps its original wording and August 2026 date because the verification pass found no official source for it.

Common misreadings

  • “Level H recovers ≈30%, so a logo can cover ≈30%.” Codeword recovery is not area. The measured cap is 16%, the default 12%, and the gap between them is a real print’s headroom.
  • “The size readout is the symbol size.” It is the image size, quiet zone included; the symbol is 4 modules narrower on every side.
  • “A ratio above 4.5:1 means the code is fine.” Only with dark modules on a light background; the inverted check is separate.

Questions

Why was my logo refused at 20% when level H recovers ≈30%?
Because the two figures measure different things. Level H recovers ≈30% of erroneous codewords, but a centred knockout produces burst erasures that use the margin far faster than scattered damage. The engine's decode tests found that 20% of the area fails on clean rasters while 16% decodes, so the cap is 16%, the default 12%, and the request is refused rather than clamped.
Why does the photo-woven style refuse my link?
Photo weaving is decode-proven only up to version 4, about 34 ASCII characters at level H and fewer with emoji or accents. A longer destination encodes to a denser symbol whose pure centre squares shrink below the decoder's sampling viability. Use a short link, or the classic, heart or framed style, none of which carries the version cap.
Can a photo-woven code also carry a centre logo?
No. The photo already spends the decode margin across every data cell, and the halftone renderer refuses a logo outright. For decoration that cannot touch the code, use the framed composite: the rendered code sits byte-for-byte on an opaque panel drawn above the frame art.
My colours measure well above 4.5:1. Why is the code still flagged?
Ratio and polarity are checked separately. A light foreground on a dark background can have a high ratio and still be flagged as inverted, because the engine's note records that light-on-dark codes are not reliably read by all scanners. The classic maker warns; the artistic styles refuse. Put dark modules on a light panel instead of inverting the code.
Does the maker upload my logo or photo to measure any of this?
No. The logo must already be a data: URL image in the browser, remote addresses are refused, and the photo is read as pixel data on your device. Encoding, contrast, logo geometry and halftone quantisation all run in the browser tab.

Everything here runs in your browser: the tools compute on your device and the Studio’s package is assembled on the device. The methodology documents every rule the tools apply.