Online QR Code Decoder: Scan and Read QR Code Images
What Is QR Code Decoding
QR decoding turns an image back into the original text payload. Unlike generation, the decoder must find finder patterns, estimate the module grid, and restore data. This site's QR code decoder does that entirely in the browser—images never upload.
QR Code Structure
| Component | Function |
|---|---|
| Finder Pattern | Three corner squares for position and orientation |
| Alignment Pattern | Helps positioning on larger versions |
| Timing Pattern | Alternating modules for grid coordinates |
| Format Information | Error-correction level and mask |
| Data Area | Encoded payload |
Error correction (decoder view)
| Level | Approx. recoverable area | Meaning |
|---|---|---|
| L | ~7% | Clean images, dense data |
| M | ~15% | General use |
| Q | ~25% | Print / light damage |
| H | ~30% | Harsh environments, planned center cover |
Correction repairs area damage to data modules. It does not replace a missing finder pattern.
Implementation notes
The QR code decoder uses jsQR (^1.4.0):
| Item | Behavior on this site |
|---|---|
| Pipeline | FileReader → Image → canvas.drawImage → getImageData → jsQR(data, width, height) |
| Library options | No options object (jsQR defaults) |
| Preprocessing | On failure, tries original → grayscale → invert → grayscale+invert; no descreen / perspective fix |
| Input | accept="image/*"; file picker, drag-and-drop, clipboard paste |
| Output | Decoded text plus preview only—UI does not show version/location |
| Privacy | Fully local |
Generate with the QR generator (qrcode, monochrome PNG) or QR designer. If the payload is a URL, inspect it with the URL parser / URL params parser. Base64 blobs → Base64 encoding guide.
Why You Need QR Code Decoding
- Read codes on cards, posters, packaging
- Preview URLs before opening (cheap safety habit)
- Extract text, Wi‑Fi strings, vCards
- Debug your own generated codes
- Decode desktop screenshots without a phone
How to Use This Site's Decoder
- Open the QR code decoder
- Upload, drop, or paste an image
- Read the text and preview
- Copy the result
On failure: crop to the code, use the original file/screenshot (not a photo of a screen), keep all three finders inside the frame.
Decoding in Code (aligned with this site)
JavaScript: jsQR (same call shape as the tool)
import jsQR from 'jsqr';
function decodeQRCode(imageData) {
// Site tool: no options — library defaults apply
const code = jsQR(imageData.data, imageData.width, imageData.height);
if (code) {
return {
data: code.data,
location: code.location,
version: code.version,
};
}
return null;
}
async function decodeQRFromFile(file) {
const img = new Image();
const url = URL.createObjectURL(file);
return new Promise((resolve) => {
img.onload = () => {
const canvas = document.createElement('canvas');
canvas.width = img.width;
canvas.height = img.height;
const ctx = canvas.getContext('2d');
ctx.drawImage(img, 0, 0);
const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
resolve(decodeQRCode(imageData));
URL.revokeObjectURL(url);
};
img.src = url;
});
}
The web UI surfaces code.data. When a non-original preprocess pass wins, a hint under the result names which variant succeeded (grayscale / invert / grayscale+invert). Inverted (light-on-dark) codes are covered by those passes before giving up — you do not need a separate “force invert” toggle.
Python: pyzbar (reference only—not the site runtime)
from PIL import Image
from pyzbar.pyzbar import decode
def decode_qr_code(image_path):
img = Image.open(image_path)
results = decode(img)
for result in results:
print(f"Type: {result.type}")
print(f"Data: {result.data.decode('utf-8')}")
print(f"Position: {result.rect}")
return results
URL vs text after decode
- Starts with
http:///https://→ treat as a link; inspect host/path before visiting. CJK/%XXbloat → Chinese percent-encoding. WIFI:…→ Wi‑Fi config (password in clear)—do not upload to remote decode APIs.BEGIN:VCARD→ contact card.- Else → plain text; do not assume a browser will open.
Screens and damaged codes
Photographing a screen adds moiré, sub-pixel stripes, auto-exposure, and glare. When paper works but the screen fails, feed a screenshot file into the decoder instead of a second optical capture.
Huge Retina screenshots can also fail because the module grid is tiny relative to canvas size — crop tightly around the three finders before upload. Extremely small images fail the other way: upscale with nearest-neighbor (not soft blur) or re-export a larger PNG from the QR generator.
Level H advertises ~30% area recovery, but:
- Losing one finder fails most libraries;
- This site does not descreen or straighten—blur, strong perspective, and cropped codes fail;
- Logos or dirt on alignment patterns hurt more than uniform grime.
Order of attempts: sharp original → tight crop → flat-lit print photo → only then forensic reconstruction tools. If the UI reports success via invert, the code was light-on-dark; regenerate or print with darker modules for phone cameras that assume dark-on-light.
Privacy: what local decode protects
Uploading payment codes, tickets, or WIFI: strings with passwords leaks context and secrets. This decoder stays in-browser. Same idea on the generate side: dynamic-QR vendors log redirects; local static codes leave no server trail after creation. EXIF GPS on photos can leak location even when decode succeeds—strip metadata for sensitive work.
Payload types you should recognize on sight
After a successful decode, classify the string before you click it:
| Prefix / shape | Meaning | Caution |
|---|---|---|
https://… | URL | Phishing pages use QR as much as email links |
WIFI:T:…;S:…;P:…;; | Wi-Fi join | Password in cleartext in the payload |
mailto: / tel: | Contact actions | Easy to mistype; confirm before share |
BEGIN:VCARD | Contact card | May include more PII than you expect |
| Opaque base64 / JWT-looking | App-specific | Decode only in tools you trust |
The QR decoder stays local so payment and Wi-Fi payloads never need to leave the device. Generate test codes with the QR generator when you need a known-good fixture.
FAQ
What's the Difference Between QR Codes and Barcodes?
QR codes are 2D barcodes with much larger capacity (up to ~7,089 digits / ~4,296 alphanumeric) and error recovery. To create one, use the QR code generator.
How Much Data Can a QR Code Store?
Numeric ~7,089, alphanumeric ~4,296, binary ~2,953 bytes, Kanji ~1,817 at spec maxima with low correction. Real capacity falls with version and higher ECC.
Why Can't Some QR Codes Be Scanned?
Blur, low resolution, tilt, glare, cropped finders, or overly dense modules. Use a high-contrast crop; compare with a phone camera if needed. Light-on-dark codes: this tool retries invert automatically — if it still fails, crop and raise contrast offline.
A ToolVault engineering note. More free local-first tools at the homepage.
Related Tools
Related Articles
Markdown to Word: Native Style Mapping and the Inline-Format Downgrade List
Turning a Markdown draft into a deliverable .docx: pandoc CLI vs in-browser local conversion, how headings/tables/code blocks map to native Word styles, which inline formats degrade to plain text, and why 'editable' beats 'looks right'.
Word to Markdown: Two Clean Paths and What Survives the Conversion
How to convert .docx to Markdown cleanly: pandoc CLI vs in-browser local conversion, a format fidelity table for headings/tables/images/auto-numbering, and fixes for the .doc legacy format, image bloat, and merged-cell tables.
China License Plate Rules and Validation: Standard, New Energy, and Special Formats Explained
Mainland China plate encoding rules in full: the standard blue plate, the GA36D-2018 new-energy format, armed police and embassy plates, province abbreviations and issuing-authority letters — with an online validator.