qart.uk

Free photo QR code generator

Turn a photo into a QR code that still scans — free, instant, and entirely inside your browser. The picture is dithered into the gaps between the code's modules, so the photo and the data occupy the same pixels. No account, no watermark, no limit, and the image is never uploaded anywhere: this page does the work, not a server. The tool is right below.


How it works

A scanner reads a QR code as a grid of light and dark modules, not as pixels, which leaves room to say the same thing with a picture. Each module is expanded into a block of subpixels and only its core — a single centre pixel, or a 2×2 middle if the subpixel ratio is even — has to carry the module's true value. That frees every other subpixel in the block to carry the photograph instead.

  1. The code is encoded first. Your payload, error-correction level, version and mask are settled before any image processing happens, so the pixels that matter are known up front rather than negotiated afterwards.
  2. A first error-diffusion pass fixes the data. Floyd–Steinberg dithering walks the image; where a pixel is a data point it is forced to the value the code needs, and the resulting error is pushed out into the surrounding free subpixels.
  3. A second pass dithers everything left over. The free points take whatever the photograph wants, having already absorbed the error from step 2 — which is why the result reads as a continuous-tone picture rather than a code with a photo pasted behind it.

The finder squares, timing lines and alignment patterns stay locked by default. They are what a scanner uses to find and square up the code at all, and dithering them is the fastest way to make something that looks better and scans worse. The output is a 1-bit PNG, which is what you want for print.

Getting one that actually scans

Two knobs decide this, and the defaults are already the safe ones. Error correction defaults to H, the highest of the four levels — it spends more of the code on redundancy, which is exactly the budget the dithering spends. Subpixel ratio is how many subpixels wide each module gets, and it defaults to 4 for a reason worth knowing: an even ratio leaves each module a 2×2 core of true value, while an odd ratio leaves a single centre pixel. That is 4 subpixels in 16 at ratio 4, against 1 in 9 at ratio 3 and 1 in 25 at ratio 5 — and it is most of what a scanner has to work with once a camera has blurred the block together. Swept across six photographs, ratio 4 decoded every time where ratio 3 decoded a quarter of the time. Ratio 3 is still the prettiest and it is still there; it just is not the safe choice it looks like.

Shorter payloads scan better, always. A long URL needs a denser code, which means smaller modules and less room per module for the photo. If a code is fighting you, shortening the link does more than any other change.

Every code this page makes is decoded before you are told anything about it. The check runs in your browser, on the exact PNG the download button gives you, and it also shrinks the image until it stops decoding — that number is the closest thing to “how far away can a phone be” we can measure without a camera. It is the same promise the paid Studio makes with its GPU detector, kept locally so this page still talks to no server at all. It is a real check, not a guarantee: scan the result with an actual phone before you commit it to print, especially at small sizes or on anything glossy.

Where the technique comes from

The error-diffusion approach here is a port of Andrew Tunnicliffe's dithered QR codes, which is the clearest treatment of the two-pass idea we know of. The older ancestor is Russ Cox's QArt codes, which established the point this all rests on: a QR code has enough slack that you can choose what the redundant bits look like. Neither of them is responsible for our bugs.

If a dithered photo is not what you wanted

You want generated artwork, not your own photo
The Studio runs a diffusion model against your payload and checks every image with a real detector before you keep it. Paid, in prepaid credits, and it will tell you which images failed rather than quietly hiding them.
You want to change the destination after printing
A dithered code encodes your URL directly, so it can never be re-pointed — the trade being that it does not depend on us still existing. If you need to retarget later, claim a free code from the pool instead: those encode a short qart.uk link, so every copy already printed follows when you change where it goes.
You want one from a script or an agent
This tool has no API — there is no server side to call. The paid endpoints do; Add this to your agent is the human setup, and llms.txt is the map.