A code on a screen either works or it doesn’t, and you find out in a second. A printed one fails weeks later, on somebody else’s phone, in worse light than you tested in — by which point you have five thousand of them. Six things decide it, and every number below came from generating real codes and reading them back with two independent decoders.
This is the one decision that removes a whole class of problem. A PDF or EPS holds the code as shapes, so the printer’s own raster stage draws it at whatever resolution the press runs at — 300, 600, 2400 dpi — and the module edges stay exact at any size. A PNG holds pixels, and every later resize has to interpolate them.
We did measure how much that actually matters, and the answer is less than the folklore suggests. Rendering the same code at one pixel per module upward, it decoded on both engines from 1 pixel per module — the whole image only 237 px at the smallest — across all 10 sizes tried. Then we took a finished PNG and rescaled it the way a layout program would, to 8 sizes including deliberately awkward fractions down to 1.00 pixels per module. Every one still read.
So the honest version is: pixel count is rarely what kills a printed code. Physical size, contrast and the quiet zone are. Take the vector anyway, because it costs nothing and it means nobody downstream can resample it badly — but if all you have is a PNG, it is probably fine.
| Format | Give it to a printer? | Why |
|---|---|---|
| Yes | True vector, page sized in millimetres, opens anywhere | |
| EPS | Yes — often what they ask for | True vector, the format most print workflows expect |
| SVG | For a designer, yes | Vector, editable in Illustrator or Figma |
| PNG | Workable | Pixels. Fine at size, but do not let anyone stretch it |
| JPG | No | JPEG compression rings around exactly the hard edges a scanner looks for |
A module — one little square — should not fall much below 0.4 mm in print. Below that, ink spread on paper and the camera’s own blur start merging neighbours. How wide that makes the whole code depends entirely on how much you put in it, because more content means more modules in the same square:
| Printed width | Module size (typical link) | At 300 dpi that is | Verdict |
|---|---|---|---|
| 20 mm | 0.49 mm | 237 px, 5.8 dots per module | Tight — short content only |
| 30 mm | 0.73 mm | 355 px, 8.6 dots | Comfortable for print |
| 50 mm | 1.22 mm | 591 px, 14.4 dots | Poster, packaging, table tent |
| 80 mm | 1.95 mm | 945 px, 23 dots | Read from across a room |
A rough working rule for distance: a code scans from about ten times its own width. A 30 mm sticker is comfortable at arm’s length; a poster read from three metres wants 300 mm. The panel under the generator does this sum for the code you actually build, because guessing from a table is how codes end up too fine.
The empty margin around the pattern is not styling — it is how a scanner knows where the code ends. The standard asks for four clear modules. On a white page you cannot tell whether a generator included it, which is exactly why it gets dropped. Put the same code on a dark background and the difference is total:
| The code sits on… | With the standard margin | With none |
|---|---|---|
| a white page | scans | scans |
| a dark background | scans | fails |
Sweeping the margin one module at a time, the code stopped reading once the clear space ran out. Design agencies trim it constantly, because on the artwork it looks like wasted space. It is the cheapest thing on this page to get right: leave it at four, and if the code sits on a coloured panel, give it its own white tile rather than trusting the panel.
Brand colours are fine until they are not, and “looks dark enough” is not a test. Stepping a grey foreground against white and decoding at every step, everything at a contrast ratio of 4.06:1 and above read, and everything at 4.00:1 and below failed.
So under 4:1 is refused outright by the generator, and 4:1 to 7:1 is flagged — it reads from a clean file, but leaves nothing spare for a phone camera pointing at a menu in a dim restaurant. Two further rules that catch people out in print: never invert (light code on a dark ground) unless you have tested the actual scanners, because many refuse it; and remember that ink on uncoated stock goes darker and spreads, so a pair that measures fine on screen has less margin on paper than you think.
Higher error correction lets a code survive scuffing, a coffee ring or a fold. It also makes the code bigger and hold less:
| Level | Recovers about | Maximum characters | Use it when |
|---|---|---|---|
| L | 7% | 2953 | Content is long and the code is protected |
| M | 15% | 2331 | The sensible default |
| Q | 25% | 1663 | Print that will get handled |
| H | 30% | 1273 | A logo, or a rough environment |
For print, Q or H is usually right. But note the trade in the last column: H holds only 1273 characters, so a long contact card physically cannot use it. Long content belongs behind a short link, which also makes the code coarser and easier to print.
“Level H recovers 30%, so my logo can cover 30%” is false, and it is what breaks printed codes months after they were made. Recovery is counted in codewords spread across the whole symbol; a logo destroys a solid block in one place. Sweeping a centre block across payload lengths and levels, the largest that still read at level H covered 15.2% of the code’s area on a long payload — nowhere near 30%.
There is no safe percentage to print on a slider, because the workable size depends on how much content is in the code as much as on the level. So the generator does not print one: it decodes your actual code, with your actual logo, and tells you whether your content came back before you download it. For anything going to print, that check is the only one worth trusting.
Everything on this page is generated in your browser — the page has no fetch, no XMLHttpRequest and no form, so a link, a menu or a payment address never leaves your machine. The codes are static, so there is no subscription that can switch your print run off.