Your logo, as a QR. Not behind it.
QR codes haven't changed visually in 25 years. The standard pattern — a black square with a logo punched in the middle — has become the universal short-circuit for 'scan to open something on my phone.' Here's a different approach.
If you've made a QR code in the last decade with anything other than a black-and-white generator, it looks like this:
- A black square (the QR data + ECC).
- A small clear circle in the middle.
- A logo in that circle.
Your logo is a passenger inside the QR. The QR is still a square.
We shipped something different at qrlia: instead of putting the logo *behind* the QR, we put the QR *inside the logo's silhouette*. The whole black region of the rendered code takes the literal outline of your brand mark. Every visible black pixel is a real, scannable QR module.
The constraint that makes it possible
The QR Code spec (ISO/IEC 18004) defines four error correction levels:
- L — recovers up to ~7% of modules
- M — ~15%
- Q — ~25%
- H — ~30%
That last 30% is the budget. At ECC level H, you can lose almost a third of the QR's modules and the Reed-Solomon decoder reconstructs the original message.
Centre-logo QRs already exploit this — they punch a small hole and ECC-H takes the loss.
We push it harder: instead of a small central hole, we drop everything outside the logo's silhouette.
What you can't drop
The QR scanner needs:
- 3 finder patterns (the corner squares with the inset square)
- Alignment patterns (5×5 blocks; positions per ISO 18004 Annex E — version 7+ has up to 49 of them)
- Timing patterns (alternating dark/light at row 6 + col 6)
- Format info (15 bits encoding the ECC level + mask pattern, in TWO L-shaped strips around the finders — the bit most "logo QR" libraries miss)
- Version info (versions ≥7, two 6×3 blocks)
- The dark module — a single always-dark cell at
(col 8, row 4*v + 9). Yes, the spec literally calls it "the dark module."
Mask any of those and the scanner can't even locate the QR. It fails before it gets to the data.
Coverage math
Once you know what you can't mask, the question becomes: how much of the rest can you safely drop?
- ECC-H tolerates ~30% module loss.
- Function patterns are ~15% of modules in typical sizes.
- That leaves ~85% as data modules subject to the silhouette mask.
- If your silhouette covers
c%of the canvas, you drop(1-c)%of the data modules. - For reliable scans across cameras + lighting + noise, drop rate must stay under ~25%.
- So coverage
c ≥ 0.75for safety.
In practice, qrlia sets the threshold at c ≥ 0.70 with auto-fit. If your uploaded silhouette is below 70% coverage, we scale it up uniformly until it hits 80%, capped at ~3.4× zoom. If even at max zoom it doesn't reach 70%, we reject the silhouette and ask you to thicken the logo.
This is the part most implementations get wrong: they happily render a silhouette QR with 50% coverage, ship it to the user, and the QR fails to scan in the wild. We'd rather upset you at upload time than ship you an unscannable QR.
Logos that work, logos that don't
Works: filled circles, ovals, shields, rounded squares, abstract brand marks (the qrlia mark, the Apple logo, the Castle Group CG mark), most word marks when the letters are filled rather than outlined.
Doesn't work: single horizontal strokes (a Nike-swoosh-style mark — coverage tops out around 30%), thin underlines, slim wordmarks, outlined logos with transparent fills.
We're publishing the fixture set + the scan-rate bench script in our docs so you can validate your own silhouettes before printing.
Try it
Logo-shaped QR ships on Pro at €12/mo. The designer at qrlia.com/designer lets you upload a silhouette PNG/SVG and watch the QR morph in real time. If you want the algorithm in code form, the technical write-up is on dev.to.