← Hashito System Home 日本語 Tools Blog Posters

Everything runs inside your browser. Your image is never sent to a server.

Waiting for an image

Drop in a photo that contains a QR code. Restoration starts as soon as it loads.

1. Image and controls

Drop in a picture containing a QR code
Click to choose / drag & drop / paste with Ctrl+V
Try a sample

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.

What happens after loading

What to try next

Advanced controls (regions, corners, preparation)

1. Mark the unreadable regions

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.

2. Place the four corners by hand

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.

3. Image preparation

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.

4. What the run did

Things to try when it will not read:
· Drag on the preview to mark the unreadable regions (they are handed to error correction as erasures)
· If the grid will not line up automatically, place the four corners by hand
· For small images raise the scale. If the picture is faint or scuffed, turn on flat-field
· If you can retake the photo, shoot head-on in bright even light, avoid reflections, and fill most of the frame with the code
· A code at error correction level L can only be recovered up to about 21% of its modules. Damage beyond that limit cannot be recovered even in principle

2. Result

No result yet. Load an image on the left and the recovered content appears here.

This contains a URL. Check the content first, and only open it by typing it into your browser yourself if you need to.
What was done

Only the steps that actually ran are listed, in the order they ran.

    Recovered modules (click to flip black / white)
    black module white module treated as erasure edited by hand
    Why an unreadable QR code can still be recovered (how error correction, sharpening and binarization work) is explained in detail in “How to restore a QR code that will not scan from a photo” (Japanese).

    About the QR Code Photo Restore tool

    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.

    Erasure correction doubles the correction power

    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.

    Checking mechanically whether the result is correct

    If guessed values happen to decode, the tool would display the wrong content as “recovered”. Three checks are therefore applied.

    1. Do the syndromes come out zero? This confirms the result is a valid codeword after Reed-Solomon decoding.
    2. How much correction capacity was left over? When the number of erasures exactly matches the capacity, decoding “always succeeds” and proves nothing. Only when at least two codewords of capacity remain unused is the result called Verified.
    3. Does the padding after the terminator follow the specification? The alternating 0xEC / 0x11 bytes that follow the end of the data must match.

    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.

    Angled shots, and images with missing finder patterns

    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.

    Parallel processing

    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).

    What it can and cannot do

    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”.

    Frequently asked questions (FAQ)

    Is my image uploaded to a server?

    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.

    What is erasure correction, and how is it different from ordinary error correction?

    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.

    Can I tell whether the recovered result is correct?

    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.

    Can it recover a photo taken at an angle, or one where a finder pattern is 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.

    Is it fast?

    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.

    Free educational posters for students →