Make a code
Scan a code
Reads SPQR and ordinary QR codes. Everything happens in your browser. On a phone, the full-screen scanner is easier.
How it works
Your text is split into two or three parts, and each part becomes an ordinary QR code. All of them use the same QR version, so they line up square for square. Each one is then given its own colour channel: a square is dark in the red channel wherever layer 1 is dark, dark in green wherever layer 2 is, and so on.
The parts every QR code has in common (the three big corner squares, the timing lines and the alignment marks) are dark in all layers, so they come out black, just like a normal QR. That gives a scanner something familiar to lock on to.
To read it, the scanner splits the photo into its red, green and blue channels. Each channel is a plain black-and-white QR code, which goes to a standard decoder (jsQR) with all of its perspective correction and error correction. The pieces are then joined back together. On a phone camera, layers that are read in different frames are combined too.
Because each layer only carries half or a third of the data, it needs a smaller QR version: fewer, bigger squares. In simulated camera tests with blur, colour bleed and JPEG compression, a longer message decoded from about three-quarters of the width a plain QR needed. For very short messages, a plain QR is just as good.
Plain QR readers can't read SPQR codes. Point people to the scanner at rotwang9000.github.io/SPQR/scan, or use the @rotwang9000/spqr-code library.