A QR code can hold a logo because of error correction: part of every code is spare data, from which a reader rebuilds whatever it cannot read. A logo uses that budget on purpose. Use too much of it and the code stops scanning.
The budget per level
| Level | Restores about | With a logo |
|---|---|---|
| L | 7% | No |
| M | 15% | Only a small one |
| Q | 25% | Yes |
| H | 30% | Yes, the best choice |
These are shares of the code's data, not of its area. A logo that covers a fifth of the width covers about 4% of the area, which leaves level H plenty of room for a crease, a reflection or a dirty lens. The higher the level, the denser the code, so it needs a little more space for the same content.
What a logo must not cover
- The three finder patterns in the corners. Readers find the code by them.
- The quiet zone, the empty margin around the code.
- More than the level can rebuild. Leave room: a code that only just scans on your screen will fail on a curved bottle.
On the command line
Make the code at level H, then place the logo in the centre with ImageMagick. The code below is 444 pixels wide, so a 90-pixel logo is about a fifth of it:
qrencode -o code.png -s 12 -m 4 -l H "https://example.com"
convert code.png \( logo.png -resize 90x90 \) -gravity center -composite code-logo.png
Read it back to check it still scans:
zbarimg --raw code-logo.png
- Set error correction to H.
- Add the logo in the middle, at about a fifth of the code's width.
- Check the code still scans, and that it still does printed small and in dim light.
- If it is marginal, make the logo smaller before you make the code bigger.