Skip to content
QRPainter Make a code

How a picture becomes a QR code that scans

A QR code has more freedom in it than it looks. QRPainter uses that freedom to choose the code's own squares so they draw your picture, then tests the result the way a phone would see it in real life.

The short version

  1. We turn your picture into a grid the size of the code (37, 57 or 77 squares across) and work out which areas matter most: edges, faces, text and the centre.
  2. We make a short link for your code. After the link, every QR code has spare room that scanners ignore. We fill that room so the squares fall where your picture wants them.
  3. We draw four versions and test each one in the Scan Lab. You pick the one you like; anything below 70 comes with a warning.

Why the picture can be the code

A QR code stores your link, then error-correction data that lets phones read it even when part of it is damaged. That data isn't random: it is calculated from everything before it. Change the spare bits after the link and the whole pattern changes in a predictable way.

Because the relationship is predictable (mathematically, it is linear), we can work backwards. We list the squares that matter most for your picture, in order, and solve for spare bits that make as many of them as possible come out the right colour. Russ Cox described the idea as "QArt codes" in 2012; we add automatic importance maps, a brush to protect key areas, three render styles and testing.

This is different from a logo pasted in the middle of a code. A pasted logo covers squares and relies on error correction to survive the damage. Here nothing is covered: the picture is made of real, readable squares.

The three styles

StyleWhat you seeBest for
SquaresThe picture drawn with the code's own squares, in two coloursBold logos, small prints, maximum reliability
Fine dotsEach square becomes a block of fine dots; the dots around its centre follow the pictureDetailed pictures, two-colour print
IllustratedLike fine dots, but the picture keeps its own coloursFull-colour logos, mascots, invitations

In the dot styles, at least 72% of every square's area keeps the code's colour, centre included, so a phone that sees the code slightly blurred still reads the right value.

The Scan Lab

Every version is rendered, then degraded in simulation eleven ways and read by three independent QR decoders: ZXing, OpenCV and WeChat's detector. A test passes only if a reader returns the exact link.

ConditionSimulationWeight
Clean6 pixels per square1
Small3 pixels per square, like a business card across a table1
Tiny2 pixels per square0.5
BlurBlur of about a third of a square1
Heavy blurBlur over half a square0.5
Rotated12 degrees1
PerspectiveSeen at an angle1
Low contrastDark areas lifted to grey, as with faded ink1
JPEGQuality-30 compression1
Print simulationInk spread, gamma shift and paper noise1
Uneven lightA shadow falling across the code1

For each condition, half the credit comes from at least one reader succeeding and half from how many of the three do. The Scan Score is the weighted average, from 0 to 100. Codes need 70 to download without a warning.

Simulations are not phones. We are running a print study on real phones and will publish the results, method and data on this page. Until then, test your final print with two phones before a large run.

How big to print

Start with a 4 cm proof for a code read at arm’s length. Detailed designs, low contrast and viewing at a distance can require a larger code. Scan a proof on the final material with several phones before ordering a print run. Always leave a light border around the code at least four squares wide.

Print a sample check sheet to compare sizes on your own printer and phones.