QArt Codes, The Better Way To Put Picture In A QR Code

[Russ Cox], current Googler and formerly of Bell Labs, posted an awesome guide to putting images in a QR code. Unlike this terrible attempt I wrote last August, [Russ]’s method does much more than simply paste an image into a QR code and hope the error correction passes. This new method generates a unique URL to be encoded for each QR code. In other words, the embedded image is actually part of the QR code and not just a copy and paste attempt.

The basis of [Russ]’ hack is the ability to change the message contained in a QR code to be made of either ASCII/UTF-8 or decimal numbers coded as binary. By appending an anchor tag (i.e. http://swtch.com/pjw/#123456789...) to the URL that will be encoded, [Russ] can change a whole bunch of pixels in a QR code to make just about any image.

With a few tricks like building new Reed-Solomon encoded blocks, [Russ] can change where in the pixels required by the QR code are placed. This allows for the full-width image of PJW’s binary likeness to be displayed in the QR code.

[Russ] put up a QArt coder that allows anyone to put a pixelated image in any QR code. [Luke Shumaker] (thanks for sending this in, [Luke]) took this tool and put the ‘ol skull ‘n wrenches inside a QR code pointing to hackaday.com. Very nice work from [Russ], and puts my work to shame. I’ll go cry in a corner now.

22 thoughts on “QArt Codes, The Better Way To Put Picture In A QR Code

  1. I was attempting something like this, but I only got so far as appending the anchor like he did to fudge the data, and picking the mask that fits best.

    He takes it to a whole new level of maths I can’t understand by hacking the reed solomon codes as well. Bravo.

  2. From a coding theory standpoint, I’ll point out that this isn’t so very different (informationally) from pasting the logo into the QR Code.

    Both of them sacrifice a modicum of robustness to achieve the graphic. The pasted-in logos do this by destroying some data, while this new approach does it by forcing the code to represent a much larger string.

    1. This method, at least in theory does not degrade the integrity of the code nearly as much as the other way, which relies on error correction fixing it.

      In theory, this provides a completely valid code, although it violates the masking parts of the spec designed to make the code the most readable.

      In the context of a url, his anchor adding technique is not particularly harmful. It is just replacing otherwise unused code space with funged data.

    1. It’s not possible for all QR code/URL combinations.

      Simple example. Let’s say you wanted to change ‘hackaday.com’ to ‘backaday.com’ You would do this by changing the ‘h’ to a ‘b’.

      ‘h’ has a binary ascii value of 01101000 and ‘b’ has a binary ascii value of 01100010. You can change the second-to-last 0 in the ‘h’ to a 1, but since you can’t change the 1s to 0s, you’re left with ‘jackaday.com’

      That’s a simplistic explanation, but you get the point. Also, i’m not even going to check jackaday to see see if it exists.

      1. No that example is too simplistic. The original hackaday QR hack worked despite a chunk of the code being obscured by a picture. Individual squares are not equal to individual bits, but the output of some forward error correction algorithm.

        I theorize it should be equally possible to fool the reader into flipping 1s to 0s as it is 0s to 1s, but there is a limit to how many bits can be flipped.

        Just getting a reader to point a server you have control of would be doing well. Once there, it doesn’t matter what the page requested actually is as you can just create a soft link to suit the hack.

  3. Your right, this is a much better way of putting a picture into a QR code, the previous method sucked compared to this, the guy who did the first one should kill himself. ;)

Leave a Reply

Please be kind and respectful to help make the comments section excellent. (Comment Policy)

This site uses Akismet to reduce spam. Learn how your comment data is processed.