What this tool does
The QR maker does four things in order, all in the browser tab. A builder turns your fields into one string in the format a reader recognises for that action. An encoder turns the string into a grid of modules at the smallest symbol version that holds it, at the error-correction level the style requires. A renderer draws the grid as classic squares, a centre image on a protected knockout, a photo woven into the data cells, or heart-shaped modules, always inside the quiet zone. The result is offered as SVG and PNG, with your colours’ contrast and the symbol version reported under the preview.
Every rule below is the engine’s own, and every figure was computed by it at build time on fixed, fictional inputs such as https://example.com/winter-fair-2026. Two guides go deeper: how the QR maker encodes ten payload types walks every builder with its escaping rules and field errors, and logo and photo QR codes and the decode margin follows what a logo, a photo, weak contrast and small print each cost. The methodology collects every tool’s rules.
Ten actions, one string each
The action you choose decides which builder runs. Each validates its own fields and returns either the exact string the encoder receives or errors tied to the fields that are wrong. A URL is validated but never shortened or rewritten. A few inputs the builders do reshape. Phone numbers are normalised to E.164 form, dropping spaces, dots, dashes and parentheses and reading a leading 00 as +, so the fixed +46 8 123 456 78 is emitted as tel:+46812345678 for a call and, because wa.me takes digits only, as https://wa.me/46812345678for WhatsApp. A network’s Wi-Fi security is folded to one token — the Wi-Fi row below was entered as WPA2 yet its emitted string carries the WPA token, because WPA2 and WPA3-Personal both map to it. And map coordinates are rounded to a fixed precision: the fictional 59.3293007, 18.0686789 is emitted as geo:59.329301,18.068679. Beyond those, the only changes are the escaping each format specifies, which the ten-payloads guide lists field by field.
| QR action | What the builder emits | Characters | Version | Modules per side |
|---|
| Website URL | https://example.com/winter-fair-2026 | 36 | 3 | 29 × 29 |
| Plain text | Winter Fair, Hall C, doors at five | 34 | 3 | 29 × 29 |
| Wi-Fi login | WIFI:T:WPA;S:Hall C Guest;P:mulled-wine-2026;; | 46 | 4 | 33 × 33 |
| Contact card | BEGIN:VCARD … END:VCARD (9 lines) | 173 | 9 | 53 × 53 |
| Email | mailto:stalls@example.com?subject=Winter%20Fair%20stall&body=One%20table%2C%20please | 84 | 5 | 37 × 37 |
| Phone call | tel:+46812345678 | 16 | 2 | 25 × 25 |
| SMS message | sms:+46812345678?body=Reserve%20a%20stall | 41 | 3 | 29 × 29 |
| WhatsApp | https://wa.me/46812345678?text=Reserve%20a%20stall | 50 | 4 | 33 × 33 |
| Map location | geo:59.3293,18.0686 | 19 | 2 | 25 × 25 |
| Calendar event | BEGIN:VCALENDAR … END:VCALENDAR (10 lines) | 221 | 11 | 61 × 61 |
Length is what the version tracks. The phone call string, at 16 characters, fits version 2; the calendar event, at 221 characters, needs version 11, a 61-module side against 25, so it wants far more room at the same print. Every row above was encoded with no level requested; the engine’s default request is level M, though the level actually encoded can come back higher, as the error-correction section below explains. The maker, by contrast, always requests a level and opens at H, which costs more room for the same string — the website URL above is version 5 at level H, not 3. Each format is tied to a named specification in the ten-payloads guide; a blank URL returns “Enter a URL.”
The quiet zone is drawn every time
Whatever the style, the renderer adds 4empty modules on every side of the symbol, and no control in the maker removes them. 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). On the example destination the encoder returns a version 3 symbol of 29×29 modules, and the rendered image is 37×37 modules once the margin is counted. That outer band is part of the code, not padding to crop; a keyline or caption tight against the modules breaks the rule the QR codes on promos guide opens with.
Error correction: a default, a selector, and a policy that overrides both
A QR symbol carries redundancy, and the four levels set how much. The reference encoder the engine vendors describes them as tolerating ≈7% (L), ≈15% (M), ≈25% (Q) and ≈30% (H) erroneous codewords (source, 2026-10-02). The engine encodes at level M when no level is requested, but the maker never leaves the level unrequested: the classic style exposes all four in a selector that opens with H selected, and the other three styles always pass H.
Encoded plain, the example destination comes back at level M, version 3. Encoded with a logo, the same text comes back at level H, version 5, 37×37 modules, with ecForcedByLogo set to true, because the logo destroys modules that error correction must reconstruct. That flag is the engine’s, and it is raised only when a logo is present and the level requested was not H; this example was encoded with no level requested, so the engine both raised the level and set the flag. The maker already requests H for the centre-image style, so in the maker the flag stays false and the level shown is the one asked for. The renderer checks too: a logo over a model encoded lower is refused with “A logo overlay requires error correction level H. Re-encode with the logo option set.” The level reported may be higher than requested, never lower, since the reference encoder raises it whenever that does not increase the version.
Centre image: a measured cap, refused rather than clamped
The image sits on a knockout square filled with the background colour first, and the knockout — image plus a 1-module pad — is what obscures modules. The engine caps it at 16% of the symbol area, excluding the quiet zone, and fills in 12%when a caller requests no area. The maker sends its own request, which the engine checks against the same cap; the figures below are computed at the engine default. The cap is measured, not derived: the engine’s note on the constant records that with a worst-case opaque dark logo on clean, undegraded rasters, the decoder fails at the larger area it tested on the symbol versions it names, while 16%decodes. That failing area and those versions live in the comment rather than as exported constants, so this page does not restate them as figures. Level H’s ≈30% codeword recovery is not ≈30% of the area, because a centred knockout produces burst erasures that spend the margin far faster than scattered damage.
On the example logo model the default knockout is about 12.8of the symbol’s 37 modules on a side, the square root of the area fraction, leaving about 10.8 modules for the image. 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.”
Photo-woven and heart styles: what stays pure
The photo-woven style splits each data cell into a three-by-three grid, shows the photo in the eight outer subcells quantised to three tones, and draws a pure square in the module colour at the centre, 50%of the cell side — the measured floor: the engine records that the one smaller centre it tested failed to decode, and says nothing about the values in between. Finder, alignment and timing cells and the quiet zone stay pure, and no logo may be stacked on a photo-woven code.
The hard limit is length. Photo weaving is decode-proven only up to version 4, about 34 ASCII characters. The example destination, fine for the other styles, encodes to version 5 at level H and is refused: “Photo-woven codes need short content — use a short link or pick another style. This content needs a version-5 code; photo weaving is decode-proven only up to version 4 (about 34 characters, fewer with emoji or accents).” A shorter fictional link, https://example.com/wf26, is version 3 and renders as 37×37 modules.
Heart modules keep each cell dark. Each heart covers 97%of its cell, a decode-verified figure chosen so a reader’s sampling grid still reads the cell as decisively dark, and finder and alignment patterns stay classic squares. The decode margin guide follows each cost through to print.
How to read the status line
Under the preview the maker reports one figure always and a second only when the first passes. The first is the WCAG 2.x relative-luminance contrast ratio of your two colours, computed from the hex values, shown to one decimal, and compared with 4.5:1, the Level AA minimum for text: “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). The second is the symbol version, which the line shows when the colour pair passes both the contrast and the polarity check; when either fails, the warning text takes the version’s place.
On the colours the maker opens with at the time of writing, #14201c on #fbfcfa, the ratio is 16.28:1, which the maker shows to one decimal as 16.3:1, and the line stays green with the version beside it. A grey #8c8c8c on white measures 3.36:1 and turns it amber: “Low contrast (3.36:1). Scanners may fail below 4.5:1 — darken the foreground or lighten the background.” Polarity is checked separately: the starting pair swapped measures the same 16.28:1 yet is flagged, “Light-on-dark (inverted) codes are not reliably read by all scanners. Prefer dark modules on a light background.”
The classic and centre-image styles warn and leave the decision to you, as the methodology’s colour doctrine sets out. The artistic styles refuse; the grey pair in the heart style returns “Artistic styles require at least 4.5:1 contrast (got 3.36:1) — decoration already spends decode margin.”
Exports and what the print size means
The SVG download is the rendered markup itself. It carries a nominal pixel size — the module count, quiet zone included, times the pixels per module the maker passes to the renderer — but the symbol is drawn as paths in module units inside a viewBox, so it rescales to any print size without resampling. The PNG download rasterises the same markup at the fixed square size its button names. The engine’s own PNG presets, 3 of them, run to 2048pixels square, and for that size the engine’s readout — pixels divided by 300dots per inch, millimetres from inches — gives 6.83 in × 6.83 in (173.4 mm × 173.4 mm) at 300 DPI. That is the whole image, quiet zone included; divide by the module count and the plain example’s modules print 4.69 mm wide at that size, the centre-image version’s 3.85 mm, because level H added modules to the same square. Whether that is enough depends on where the code will be read, the sizing guide’s subject: its close-range rule of thumb is at least 2×2 cm (0.8×0.8 in) and its distance rule of thumb about 10× the printed code's width, figures that keep their August 2026 wording because no standards body states them.
Where the tool stops
- It checks form, not truth. The URL is not fetched and a Wi-Fi password is not tested.
- It does not decide what a phone does with the string. Two builders carry disclosures the maker shows beside their results. SMS: “Pre-filled message support varies by platform: some phones open the composer with the text, others ignore it. The number always works.” Calendar: “Calendar QR codes are less reliable than other types: native camera app support is inconsistent, and some phones show the raw text instead of an add-to-calendar prompt. Test on the devices your audience uses.”
- It does not promise a scan; the tool page still asks you to scan the export on more than one phone before printing.
- Generating and downloading a code uploads nothing: the logo becomes a data URL and the photo pixel data on your device, remote image addresses are refused, and encoding and rendering run in the tab. Saving to an account is a separate, explicit action that sends the built package, never the source files.
- It does not clamp. Whatever exceeds a limit is refused with the reason.
Common misreadings
- “Version 11 is better than version 2.” The version is a size class, not a grade; higher means smaller modules at the same print.
- “Level H recovers ≈30%, so a logo can cover ≈30%.” Codeword recovery is not area. The measured cap is 16%, the engine’s default request is 12%, and the maker’s request is checked against the same cap.
- “A ratio above 4.5:1 means the colours are fine.” Only with dark modules on a light background; the inverted check is separate.
- “The PNG size is the symbol size.” It is the image size; the symbol is 4 modules narrower on every side.
Questions
- Which error-correction level does the maker use?
- The engine's own default is M, but the maker always requests a level. Its classic style opens with H selected and lets you pick L, M, Q or H; the centre-image, photo-woven and heart styles always pass H, because decoration removes modules error correction must reconstruct.
- Why does the photo-woven style refuse a link the classic style accepts?
- Photo weaving is decode-proven only up to version 4, about 34 ASCII characters at level H. The example destination encodes to version 5 at that level, so weaving refuses it. Use a short link you control.
- Can I remove or crop the margin around the code?
- No. The renderer always draws 4 empty modules on every side and the download includes them; that band is how a reader finds the symbol's edges.
- Why was my centre image refused instead of being made smaller?
- The engine caps the knockout at 16% of the symbol area because its documented decode measurement found that the larger area it tested fails on clean rasters while 16% decodes. Requests above the cap are refused, not clamped.
- What does the version number in the status line mean?
- The QR symbol size class the encoder chose, the smallest that holds your string at the required error-correction level. The example destination is version 3 plain and version 5 with a centre image.
- Which file should I give a printer?
- The SVG whenever the printer accepts one; it scales without softening the module edges. The PNG is a fixed square whose side the download button names; at the largest of the engine's presets, 2048 pixels, the engine's readout gives 6.83 in × 6.83 in (173.4 mm × 173.4 mm) at 300 DPI.
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.