필사 모드: What Does a QR Code with a Photo Inside Pay For It — Error Correction Is a Budget
English- The Suspicion You Get Looking at a QR Code That Looks Like a Photo
- A QR Code Is Made of Two Kinds of Cells
- Where the Photo Goes — Splitting One Module into Nine Cells
- So One Cell in Nine Is Random
- Dithering — Diffusing the Error Instead of Thresholding
- The Key Idea — Diffuse the Error of the Data Modules First
- The Slack Is a Budget
- What Trips You Up in Practice — Quiet Zone and Scaling
- Wrap-Up and Sources
The Suspicion You Get Looking at a QR Code That Looks Like a Photo
You have probably seen a QR code that looks like a black-and-white photograph but opens a link when you scan it. Not a logo dropped in the middle — the whole code is a picture. The first time you see one it looks impressive, and the second thought is usually this: how does that even scan.
The answer is simpler than expected, and being simple is exactly why it matters. The part worth knowing in practice is not why it scans but what was paid for it. This post follows the explanation document for the error-diffused QR code generator published by Andrew T. and pins down what that price is.
A QR Code Is Made of Two Kinds of Cells
The original write-up divides a QR code into two parts. One is the function patterns. These are the shapes like the thick squares in the corners, and the scanner uses them to find the code and establish its orientation and size. The other is the data modules. That is everything else, and it holds the actual data and headers.
The key is the reading order. The scanner first fixes the coordinate system of the code from the function patterns, and only then reads the data modules. So the function patterns have to be very crisp, while the data modules leave relatively more room to be messed with. The distinctive QR codes brands make are using that room, and as the source puts it, scanning robustness does drop somewhat, but you can mess with them quite a lot and they generally still read.
Where the Photo Goes — Splitting One Module into Nine Cells
The technique that comes out of this is interesting. The approach the original introduces is to split one module into a 3×3 grid, leave only the single center cell in the color the data requires, and give the other eight cells to the photo.
The reason this works is in the ordering above. Using the position the function patterns provided, the scanner looks at the center of each module. As long as the center is right, the surroundings are free. So if within one grid cell you protect only the one center cell and fill the eight with picture, the code still reads and the picture still shows.
The result is a low-resolution 1-bit black-and-white photograph. The image the original gives as an example is 147×147 pixels. Divide that number by 3 and you get 49, which lines up with a QR code that is 49 modules on a side. In other words, it is the result of splitting 49 modules into 3 cells each.
So One Cell in Nine Is Random
This approach comes with unavoidable noise. The one center cell of each module has to be the color the data dictates, regardless of what the photo wants. The data has nothing to do with the photo, so from the picture's point of view the color of that one cell is effectively random.
The original states this exactly this way: one pixel in nine is effectively a random color. That is why the resulting image gets speckles as if salt and pepper had been sprinkled on it. A 147×147 1-bit image is coarse to begin with, but a good share of the coarseness comes from this one-in-nine.
There is a fix that usually comes to mind here: change some of those center pixels to match the picture. QR codes have error correction, so a few of them can be wrong and it still reads. A QR code with a logo in the middle works on exactly that principle. But the original comes to a different conclusion. We will get to it below.
Dithering — Diffusing the Error Instead of Thresholding
First the picture side of the story needs sorting out. If you reduce brightness to two black-and-white values with plain thresholding, all the midtones vanish. So the usual approach is to imitate midtones with a lattice pattern, but a regular lattice has a visible pattern of its own.
Floyd-Steinberg error diffusion takes a different approach. To carry the original explanation over directly: you start at the top left and threshold pixels as usual. Over 50 percent brightness becomes white, otherwise black. If some pixel was at 70 percent, making it white means you gave it 30 percent more brightness than it deserved. You divide that 30 percent among the neighboring pixels you have not processed yet and darken them by that much. When those pixels get thresholded, that value is taken into account.
Once the whole pass is done, each part of the image is on average closer to the original brightness. And instead of a lattice you get an irregular pattern, which is less objectionable.
The Key Idea — Diffuse the Error of the Data Modules First
Now the two stories meet. The real idea in the original is to run error diffusion twice.
The second pass is ordinary Floyd-Steinberg. It is the first pass that differs. It targets only the center pixels of the data modules. Their colors are already fixed, so you paint them the fixed color and diffuse the error that arises at that moment into the eight surrounding cells.
The error can get very large here. In ordinary dithering we choose the color, so the error never exceeds 50 percent. In this case, though, you might have to make a pixel in a very dark region pure white, and then you get a 95 percent error. The original says this sounds like a bad thing but that is precisely why diffusing it matters. Just absorbing it leaves a speckle right there; diffusing it darkens the surroundings by that much so the average comes out right.
And that gives the answer to the question deferred earlier. The original concludes that changing a few data modules to match the picture helps image quality very little while badly degrading scanning performance. Diffuse the error properly and the need to change colors nearly disappears.
The Slack Is a Budget
This is the point this post most wants to make. The axis of raising image quality and the axis of spending error-correction slack are different axes. The second error diffusion improves the picture without spending a single grain of slack. Changing data modules, by contrast, burns slack directly.
Think about what the slack is there for and it becomes clear why the distinction matters. QR codes have four error correction levels, and Denso Wave, which created the specification, states that the most widely used of them restores 15 percent. Raising the level raises the resilience but requires a larger code for the same data. And that resilience was set aside in the first place for print defects, creases, smudges, oblique angles, and dim lighting.
In other words, spending slack to make it pretty is moving a budget reserved for bad field conditions over into design. The original reaches the same conclusion: it is fine for a code going on a big screen or a poster, but if it is a paper flyer that can get crumpled, you are going to need that slack. And it adds one sentence. The fact that it reads fine off your laptop screen with your own phone does not mean a stranger with an old phone will get it off a printout in a dark place.
What Trips You Up in Practice — Quiet Zone and Scaling
The two practical warnings the original appends at the end are also worth carrying over as they are.
The first is the quiet zone. The generator hands you a small image with no margin, but a QR code needs a margin around it to scan reliably. And the color of that margin has to be the opposite of the color inside the big corner squares. Usually white, but if you made an inverted code you need a black background.
The second is scaling. When a browser displays a small image large, it interpolates it blurry by default. Blurred edges make it hard for a scanner to decide where the module centers are. Unless you turn interpolation off in CSS, this problem happens quietly.
The two items have something in common. They are fine on the screen of the person who made it and fail only in the environment of the person using it. Failures of pretty QR codes mostly arrive in this shape.
Wrap-Up and Sources
Putting a picture in a QR code is your prerogative. It is just better to use that freedom knowing what it was borrowed from. Scan failures happen in the user's hand, not on our screen, and by then the printing is already done.
- How to make error-diffused QR codes — the distinction between function patterns and data modules, the 3×3 split, the one-in-nine noise, the two error diffusion passes, the 95 percent error, and the quiet zone and scaling warnings are all explanations from this document.
- The generator and the source code — you can make one yourself.
- The Denso Wave page on error correction levels — I confirmed there that there are four levels, that the most widely used one is 15 percent, and that raising the level makes the code bigger. The exact figures for the other three levels are provided on that page only as images, so I did not write them into this post.
- The calculation that 147 divided by 3 is 49, and the statement that this corresponds to 49 modules on a side, are things I derived from the numbers in the original.
현재 단락 (1/29)
You have probably seen a QR code that looks like a black-and-white photograph but opens a link when ...