How Artistic QR Codes Still Scan: The Halftone Idea
An artistic QR code can still scan because some decoders do not judge each module as a whole. One open-source decoder, ZXing, reads one pixel at the computed center of every module. The halftone approach, described by Chu et al. in 2013, builds on that: each module keeps a correctly colored dot at its center, and the picture shows through around it. The trick fails when blur or an overlay reaches the center, so every design needs a decode test and a printed proof.
Facts checked on 17 October 2026.
What a scanner looks at, and what it skips
The structure below comes from the 2006 edition of ISO/IEC 18004; a fourth edition appeared in August 2024 and we have not read its full text. A QR code has three identical finder patterns, built from dark 7×7, light 5×5 and dark 3×3 modules in the ratio 1:1:3:1:1; finding all three tells a reader where the symbol is and how it is rotated. Timing and alignment patterns then help it place the module grid.
Once the grid is placed, the decoder samples each module. A 2022 EUSIPCO paper builds on the premise that only the central pixel of each module is sampled, but adds that nearby pixels can be sampled when the sampling grid is estimated with errors. We did not verify how the cameras built into iPhones and Android phones decode, so treat ZXing as one example, not every phone.
The halftone idea
Chu, Chang, Lee and Mitra published "Halftone QR Codes" in ACM Transactions on Graphics in November 2013. The paper's model divides each module into 3×3 submodules and binds the module's color to the center one, leaving the other eight free to follow a halftone image. Under perfect conditions, they note, any pattern with the right color at the center should leave a module readable. They change only data modules.
Think of it as a promise per module: the center is always right, and the rest may show the picture. If the decoder samples exactly the center, the picture damages no codeword, so error correction stays in reserve (our reading, not a claim in the paper). Real sampling is imperfect, and that is where the reserve gets used. The authors also describe an optional step that deliberately uses up to half of the correction capacity in their tests.
The paper is candid about the cost: it lists blur from downsampling as a limitation, because the center pixel that carries the data is easily polluted by its neighbors. In a test of five codes, three users and four phone barcode readers, halftone codes stopped working at a Gaussian blur radius of 2 pixels and a 40-degree viewing angle; matching ordinary codes stopped at 6 pixels and 60 degrees. The same paper reports that, of 100 codes made with default settings, 91 read on all four readers. The tests used one 8-megapixel phone and monitor-displayed codes, so read them as a direction, not a forecast for today's phones.
Where artistic codes break
Each row breaks the center-sampling assumption or uses up error-correction capacity. The last column marks our own reasoning.
| What you do | What goes wrong | Basis |
|---|---|---|
| Put light modules on a dark background | The 2006 edition allows light symbols on dark backgrounds, but each decoder chooses whether to try an inverted image. ZXing only does so when the caller sets a hint; jsQR tries both by default, at about a 50% speed cost. | Standard, two decoders; phone cameras not verified |
| Paint over the three corner patterns | They locate and orient the symbol, and Chu et al. change only data modules. | 2006 edition; Chu et al. |
| Leave under four modules of margin | The 2006 edition requires a quiet zone four modules wide. DENSO WAVE says letters or pictures around the code mean the required margin cannot be secured. | 2006 edition; DENSO WAVE |
| Shrink the center dots to show more picture | Less room when the sampling grid is slightly off, and halftone codes tolerated less blur and angle in the 2013 test. | EUSIPCO 2022; Chu et al.; the link to dot size is our inference |
| Tint the dots with the picture's colors | The dark-light gap can narrow. ZXing's binarizer treats an 8×8-pixel block whose brightest and darkest pixels differ by 24 levels or less (scale 0 to 255) as holding only light or only dark pixels and estimates its threshold differently. | ZXing source; the link to tinting is our inference |
Why "30% error correction" is not 30% of the area
The 2006 edition gives approximate recovery capacity of 7%, 15%, 25% and 30% for levels L, M, Q and H as a share of the symbol codewords. DENSO WAVE likewise expresses the rate as a ratio of total codewords. The standard adds that flipping one module makes its character decode as an apparently valid but different codeword, and fixing that takes two correction codewords. Its example: a version 6-H symbol has 172 codewords, 112 for correction, which can fix 56 misdecodes, or 32.6% of capacity.
So any percentage of area is a guess. In a regular symbol a codeword sits in a column two modules wide and four tall, as we read the standard's bit-placement figure, so by our inference scattered specks can touch more codewords than one solid patch of the same area. We make no claim about how much area a design may cover. To choose a level, see error correction levels explained; for finished examples, see design ideas by industry.
How to check an artistic code before you print it
- Start from level H and the shortest content you can. Longer content means smaller modules at the same print size, and DENSO WAVE says larger modules are more stable and easier to read. The data capacity guide shows how fast symbols grow.
- Check dark against light everywhere. Convert the design to grayscale. Every dark dot should be clearly darker than the light dots beside it, over bright and dark parts of the picture.
- Decode it digitally at several sizes. The free QR code checker runs in your browser without uploading the image, tests contrast and the quiet zone, re-tests at reduced sizes and flags a code that only decodes when inverted.
- Print a proof and scan it with different phones. The standard's informative annex says to verify a symbol in its final label or package configuration, because "overlays, show-through and curved or irregular surfaces can all affect symbol readability". Chu et al. saw four barcode readers on one phone perform differently, so use at least two phones, at the real distance and light. See the print size guide for minimum widths.
- If it fails, change one thing at a time. Enlarge the center dots, lower the picture's contrast, print larger or cut the content, then repeat steps 3 and 4.
What a built-in check can and cannot tell you
In the QR Maker AI editor, festival themes and pattern halftones such as the 福 character are free, and image fusion, your own picture under the dots, is a Pro feature as of October 2026 (see pricing). For halftone patterns and image fusion, the editor draws only a center dot per module, puts a solid light block under the corner patterns, alignment patterns and logo area, and sets error correction to level H.
The editor's Scan Guard check decodes the rendered code in your browser at a normal size and several smaller ones, using an open-source decoder in dark-on-light mode only. It cannot test light-on-dark codes, paper, ink, curved surfaces or any phone's camera, so the printed proof in step 4 stays. Try a design in the editor.
FAQ
How do artistic QR codes work?
Halftone-style codes keep a correctly colored dot at the center of every module and draw the picture around it, because decoders such as ZXing sample near the module's center. Error correction is the safety margin on top.
Can I put a photo behind a QR code and still have it scan?
It can work when dots stay clearly darker or lighter than their surroundings, the corners and margin stay clear, and error correction is H. No design is certain to scan, so test a printed proof.
Can I use white dots on a dark background?
The standard allows light symbols on dark backgrounds, but support depends on the app: ZXing tries an inverted image only when told to. Dark on light is safer; test any inverted design on your audience's phones.
How much of a QR code can a design cover?
The level does not translate into a percentage of area. Error correction levels are defined as shares of codewords, and one flipped module spoils its whole codeword. Test the actual file.
Why does my designed QR code not scan?
Check for inverted colors, covered corners, a margin under four modules, weak contrast between dark and light dots, and small print. The troubleshooting list covers other causes.
Sources
- ZXing project — DefaultGridSampler.java. Undated source file. Accessed 17 October 2026.
- Chu, H.-K., et al. — Halftone QR Codes. ACM Transactions on Graphics 32(6), Article 217, SIGGRAPH Asia 2013 (author-hosted PDF, National Tsing Hua University; publisher record: ACM Digital Library). Published 1 November 2013. Accessed 17 October 2026.
- ISO/IEC — ISO/IEC 18004:2006, QR Code 2005 bar code symbology specification. Second edition, published 1 September 2006 (copy hosted by Public.Resource.Org). Accessed 17 October 2026.
- ISO — ISO/IEC 18004:2024 standard page. Fourth edition, published August 2024. Accessed 17 October 2026.
- Pena-Pena, K., Lau, D. L., Arce, G. R. — Colored-QRNet: Fast QR Code Color Image Embedding. EUSIPCO 2022 proceedings. Published 2022. Accessed 17 October 2026.
- ZXing project — DecodeHintType.java. Undated source file. Accessed 17 October 2026.
- jsQR project — README. Undated. Accessed 17 October 2026.
- DENSO WAVE — Examples of problems encountered in reading a code. QRcode.com, undated. Accessed 17 October 2026.
- ZXing project — HybridBinarizer.java. Undated source file. Accessed 17 October 2026.
- DENSO WAVE — Error correction feature. QRcode.com, undated. Accessed 17 October 2026.
- DENSO WAVE — Point for setting the module size. QRcode.com, undated. Accessed 17 October 2026.