Positions that could not be read are passed to error correction as erasures, and perspective distortion is undone with a homography. Drop in an image and it restores automatically
Everything runs inside your browser. Your image is never sent to a server.
The QR codes below are real ones generated inside this page (they all encode https://hashitosystem.com/; the letter in brackets is the error correction level). Each one carries the kind of damage that happens in real photographs. Press "Try this image" to load it straight into the tool.
Drag on the source preview to enclose areas ruined by scuffs, blown-out highlights or shadows. Modules in those areas are not guessed; they are handed to error correction as erasures. Because their positions are known, erasures can be repaired at twice the rate of errors whose positions are unknown.
This is the escape hatch when the grid cannot be located automatically. Tick the box below, then click the outer corners of the QR code four times, in the order top-left, top-right, bottom-right, bottom-left. A homography is built from that quadrilateral and the version is brute-forced.
Scaling up a small image gives each module more pixels, which stabilises sampling. Flat-fielding (dividing out uneven background brightness) helps when the whole picture is faint or covered by pale scuffs. After changing anything, press Restore.
No result yet. Load an image on the left and the recovered content appears here.
Only the steps that actually ran are listed, in the order they ran.
A QR code in a screenshot or a camera photo will not scan — and most of the time the cause is scuffing, dirt, blown-out highlights, an angled shot, or low contrast. This tool keeps hold of the one piece of information that off-the-shelf QR readers throw away, namely which parts could not be read, and hands it to the erasure correction of the Reed-Solomon code, aiming at damage that ordinary reading cannot reach.
In a Reed-Solomon code, of the n codewords in a block, k are data and the remaining n-k are for error correction. When the position of an error is unknown you can repair at most (n-k)/2 of them; when the position is known (an erasure) you can repair n-k. Exactly twice as many.
For example, a version 2 / level M QR code has 16 error correction codewords out of 44 in total. Without position information only 8 can be repaired, but with it 16 — about 36% of the whole code. At level H it is 28, about 64%. This tool ranks the modules whose black-or-white value it could not settle (because of scuffs or blown-out highlights) by confidence, and sweeps how many of the lowest-ranked ones to treat as erasures. Because it searches that trade of “errors for erasures” up to the optimum automatically, it neither erases so much that the correction budget is spent, nor so little that errors are left behind.
If guessed values happen to decode, the tool would display the wrong content as “recovered”. Three checks are therefore applied.
Results that fail these checks are not discarded: they are presented as analysis candidates, clearly labelled “contains guesses”. If the content is a URL, always confirm that it is plausible before opening it.
A QR code photographed at an angle appears as a trapezoid. An affine transform can only express a parallelogram, so the grid will not fit; instead a homography is solved from four points — the centres of the three finder patterns plus the centre of the alignment pattern — and the modules are sampled after rectification.
Some photos only show two finder patterns, or one, because the rest are buried under a scuff. In that case the tool derives the module size from the single pattern it found and brute-forces the corner role (top-left / top-right / bottom-left), the version and the scale, and also tries building the grid from the four corners of the code’s outline quadrilateral. Which candidate is right can be decided mechanically by the Reed-Solomon syndromes, so producing plenty of candidates never leads to a wrong result being accepted. Some photos still cannot be located, which is why placing the four corners by hand remains available.
The binarization sweep, the evaluation of grid candidates and the erasure sweep are independent of each other, so they are split across Web Workers and run in parallel. The workers are assembled from a Blob, so this page remains a single self-contained HTML file. The number of workers is derived from the logical core count of your device (capped at four), and the rest are stopped as soon as one produces a verified result. Where Web Workers are unavailable the same work runs sequentially (same result, only slower).
Even with erasure correction, at most n-k codewords per block can be repaired. The ceiling is about 21% of the code at error correction level L, about 36% at M, about 51% at Q and about 64% at H; damage beyond that cannot be recovered even in principle. Damage whose position cannot be identified from the image (for instance a module that simply flipped value while keeping the same contrast as its surroundings) cannot be treated as an erasure, so the correction power falls back to half. When recovery fails, the tool shows how far it got — how many finder patterns were detected, the grid match rate, and how many codewords were treated as erasures — under “What the run did”.
No. Loading the image, correcting perspective, binarizing, error correction and decoding all run entirely inside your browser (Canvas, JavaScript and Web Workers). Neither the image nor the decoded result is ever sent to or stored on an external server, so you can safely use pictures you would rather keep private, such as business cards or tickets.
Error correction comes in two flavours: one where the position of the error is unknown, and one where it is known. The latter is called erasure correction. With Reed-Solomon codes you can repair at most (n-k)/2 errors whose position is unknown, but up to n-k erasures whose position is known - exactly twice as many. This tool records every module it could not read because of a scuff or a blown-out highlight as an erasure, and passes that position information to the decoder. Ordinary QR readers throw away the information about what they could not read, and that difference is often what decides whether a code can be recovered.
Yes. After Reed-Solomon decoding the tool mechanically checks three things: whether the syndromes come out zero, how much correction capacity was left unused, and whether the padding after the terminator follows the specification. When decoding succeeded with capacity to spare, the result is labelled Verified. When the capacity was used up, there is no guarantee that the result matches the original QR code, so it is clearly labelled Contains guesses. That distinction is never hidden.
For angled shots the tool solves a homography from four points - the three finder pattern centres plus the alignment pattern centre - rectifies the image and then samples the modules. If a finder pattern is missing, it brute-forces the corner role, the version and the scale starting from the single pattern it did find, and also tries building the grid from the four corners of the code outline. If none of that works you can click on the preview to place the four corners by hand. Some photos simply cannot be located automatically, so the manual escape hatch is always available.
The binarization sweep, the evaluation of grid candidates and the erasure sweep run in parallel in Web Workers. The number of workers is derived from the number of logical cores on your device (capped at four), and the rest are stopped as soon as any worker produces a verified result. On browsers without Web Worker support the same work runs sequentially: the result is identical, it just takes longer.