Despite its ubiquity, the humble QR code has been somewhat taken for granted by developers. The Quick Response (QR) code was invented by a subsidiary of Toyota to track parts through the manufacturing process. But the subsidiary, Denso Wave, has never exercised its patent and the technology is therefore free to use.
Today, we typically use QR codes to get long URLs to our phones from walls, towels, business cards, or even t-shirts; i.e. any visible surface that we can take a picture of. Here’s one I made for thenewstack.io thanks to QRFY (it uses a shortcode that will eventually go offline – so give it a try ASAP.)
Let’s play a design game. Senior software designers should always go through redesigns in their heads to practice their analysis skills. Your next job might start with an existing system that you never thought of before, even though you use it all the time. How would you expect a QR code to look and behave? How would you go about designing it from scratch? How would you test it?
But first, what do barcodes not deliver that QR codes can? Barcodes extend laterally across a surface and work quite effectively in your local supermarket. But a slight contrast on the surface can make them difficult to read at an angle. In your supermarket’s automatic checkout you can toss a package of couscous until it’s scanned, but you can’t do that with a packing crate in a warehouse.
Let’s summarize the basics of what we think you should look for in a QR code before looking at how it actually works:
- It should work well in different lighting conditions and on various surfaces.
- It needs some degree of error correction, so minor damage doesn’t render it useless.
- As it cannot update itself automatically, it will have to integrate a lot of metadata; like version information for example.
OK, so you need to know where the code is and where it isn’t. That is, to detect the position and boundaries of the container before you can read the contents inside. You’ve probably noticed those big squares that contain dots. These do the Research model. If you see the little square with a dot in it, that’s the alignment model. This confirms the angle and orientation of the image.
One thing a good developer will be aware of is the importance of meta information. This becomes more important as a project ages, as different variations and versions proliferate.
In the case of a QR code, the reader must determine the size of the content carrier. Points that intersect from one search square to another at the interior sides make the Synchronization model. These tell the reader the size of a single module and the size of the entire QR code – known as a version. Note that these appear in two places.
I’ve never seen a QR code like the one on the right, but it’s describable in the system!
Redundancy has an interesting place in any system, especially for systems that exist in nature. It stands to reason that a QR code should have more than one way to access its data, in case a small part of the code is obscured. Redundancy and error correction help achieve this – try reading the code on top with a small portion of the image hidden.
Format Information is stored and repeated in bands around Finder patterns. The format stores information about the mask, as well as the level and type of error correction.
Most developers should be familiar with masks, but the application here is a bit different. Since the pattern works best when there is a balance between dark and light areas, the idea is to remove the larger light or dark spots that disrupt the pattern. When a mask is applied to the code during creation, all points under the white part are kept, while all points under the dark part are inverted. So when the code is replayed, the mask can be reapplied to return the code to its original state. Different masks are applied to see which one gets the best result; and this stored in the format model.
It reads a bit strangely at first, but it represents the idea that software is controllable but external conditions are not. This indisputable complication always helps to create a more reliable end product. Shaping the data itself to work better with the rest of the toolchain is something you do to improve an existing solution – you never thought of doing that in the first place.
The error correction level controls the density of the code. By increasing the density of information, redundancy increases and it becomes easier to retrieve information when the code is covered; but the whole picture is more complex. This is where the intended use case comes in – where the surface is accessible and close, simple low-density code is perfectly reliable. Otherwise, trusting the correction strategies becomes more convenient.
What about data?
So after all that, where is the Data himself? Curiously, it winds down to the right (the traditional Japanese reading direction is right-to-left).
The remaining area on the other side is for math calculation Correction of errors. Reed-Solomon code is an error correction method used for music CDs, but it was originally developed to counteract noise in satellite communications. There are still various strategies that can be adopted – whether to spot an error in whole or in part and proofread the code, compare redundant areas or calculate a correction.
So there we have it. A simple premise, but filled with the normal complications of any project that has had to adapt to the environment. This brings us to the final quality a designer must have: empathy. Appreciating the work others have done to make something functional can be hard to grasp at first, but patiently undoing it is the only way to absorb it.
(I’ve wanted to write about QR code design for a while, but this article by Dan Hollick got me started and provided me with some great images, which I borrowed for this article.)