QR Code Scanner

Drop in a screenshot or a photo and see exactly what the code contains — the link, the WiFi password, the contact card — before you act on it. The image is read in your browser and never uploaded.

Quick answer: drop an image of a QR code onto this page and its contents appear as text, with the fields broken out for WiFi, contacts, payments and calendar events. A link is shown in full and is not made clickable until you have read it — which is the point, because a QR code hides its destination and that is exactly what a sticker placed over a real one relies on.
Read a code

Drop an image here

or click to choose one — PNG, JPG, WebP, GIF or BMP.
A screenshot, a photo of a poster, a code saved from an email.

Why read a code before you open it

A QR code is unreadable to a person. That is the whole appeal and it is also the whole problem: nothing about the pattern tells you where it goes, so a sticker placed over a real code on a parking meter, a restaurant table or a parcel locker is invisible until somebody has already scanned it. The practice is common enough to have a name — quishing — and it works on exactly the people who are being careful in every other way.

Phone cameras have started showing the destination before opening it, which helps, but the preview is small, it is shown for a moment, and a long address is truncated in the middle where the interesting part usually is. Dropping the image here shows you the whole thing as text, in a form you can read at your own pace, and it does not make the link clickable until you have.

There is a second case the camera cannot do at all: a code that arrives as a picture. A screenshot somebody sent you, a code in a PDF or an email, a photo taken from across a room. Your phone will not scan its own screen, and pointing one phone at another is a poor substitute for reading the file.

What it flags, and what it cannot

Four things are worth a second look, and all four are properties of the text itself rather than guesses about intent:

FlagWhy it matters
Not httpsA plain http link is readable and alterable in transit. For a login or a payment that is disqualifying.
A link shortenerThe address you can see is not the address you will land on. A shortener is normal in marketing and also the easiest way to hide a destination.
An @ before the domainIn https://paypal.com@evil.example/ the real host is evil.example; everything before the @ is ignored by the browser. It is an old trick and it still works on people.
A lookalike domainA host written with non-Latin characters can be made to resemble a familiar brand. The address bar may show it correctly and the eye still reads the wrong thing.

What it cannot tell you is whether a perfectly ordinary-looking address is trustworthy. A code pointing at a real domain over https with no shortener passes every check here and can still be a page collecting your card details. These flags narrow the field; they do not clear it.

The formats it breaks apart

Most QR codes hold a plain link, but the useful ones hold structured text in a format phones understand, and that text is not meant to be read raw. A WiFi code is WIFI:T:WPA;S:MyNetwork;P:hunter2;;, which says rather more once it is laid out as three fields. The scanner recognises and labels links, plain text, WiFi, vCard and MeCard contacts, phone numbers, SMS, email, WhatsApp, locations, calendar events, UPI and SEPA payments, crypto addresses and app store links.

That list is the same one the generator writes, which is not a coincidence — this page reads the formats that page produces, using the same decoder the generator already runs against its own output before letting you download it.

When a code will not read

Usually one of four things, in rough order of how often it happens.

Cropping tightly to the code — but leaving a little white around it — fixes most of the first two.

What crosses the network

Nothing of yours. This page contains no fetch, no XMLHttpRequest, no sendBeacon and no form, so the image has no route off your machine; it is read with FileReader, drawn onto a canvas in your tab, and decoded by JavaScript there. The only things fetched are the decoder library from jsDelivr — a static file, identical for every visitor, that carries nothing of yours — and this site's own header, fonts, analytics and ad script, as on any page here.

You can check that in about thirty seconds: open your browser's Network tab and drop an image in. If the camera is used, the frames stay in the page too — nothing is recorded and nothing is sent.

Frequently Asked Questions

Drop the image onto this page, or click to choose one. It reads PNG, JPG, WebP, GIF and BMP — a screenshot, a photo of a poster, or a code saved from an email. The decoded contents appear straight away, broken into fields where the code holds structured data such as WiFi details or a contact card. The image is never uploaded: the decoding happens in your browser, which is also why it works on a code you would rather not hand to a website.
Yes, and that is the main reason to use this. The link is shown in full as text, and it is not made clickable until you have seen it. Fraudulent codes stuck over real ones — on parking meters, restaurant tables and parcel lockers — are common enough to have a name, quishing, and they work precisely because a QR code hides its destination. This page also flags the things worth a second look: a link that is not https, a shortener that hides the real destination, an address containing an @ before the domain, and a name using non-Latin characters that can be made to resemble a familiar brand.
No. The page contains no way to send anything — no fetch, no XMLHttpRequest, no form — so the image is read by your browser and decoded by JavaScript running in the same tab. You can confirm it in about thirty seconds: open the Network tab and drop a picture in. The only requests are the decoder library itself, a static file identical for every visitor, and this site’s own header, fonts, analytics and ad script.
Any QR code, and it recognises what is inside for the common formats: links, plain text, WiFi networks, vCard and MeCard contacts, phone numbers, SMS, email, WhatsApp, locations, calendar events, UPI and SEPA payments, crypto addresses and app store links. For those it shows the fields separately rather than one run-on string, so a WiFi code tells you the network name, the password and the security type as three things.
Usually one of four things. The picture is too small or too blurred for the module edges to survive. The code is cropped, so part of the pattern or its white margin is missing — that margin is part of the code. There is glare or a strong angle, which a flat screenshot does not have but a photo of a sign does. Or it is not a QR code at all but a different barcode, which this page does not read. Cropping tightly to the code, with a little white around it, fixes most of them.
Yes, on a device with one, and the page asks first — the camera is off until you press the button and your browser prompts for permission. Frames are read in the page and nothing is recorded or sent. On a phone this is often unnecessary, since the built-in camera app already scans codes; the file route is the one that has no equivalent, because your phone will not decode a screenshot somebody sent you.
It is the other half of it. The generator writes the formats; this reads them back, using the same decoder the generator uses to check its own output before you download it. If you want to make a code rather than read one, the generator handles links, WiFi, contacts, payments, events and the rest — also without an account and without uploading anything.

Related tools