Skip to content
Utilities2026-07-015 min read

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

ComponentFunction
Finder PatternThree corner squares for position and orientation
Alignment PatternHelps positioning on larger versions
Timing PatternAlternating modules for grid coordinates
Format InformationError-correction level and mask
Data AreaEncoded payload

Error correction (decoder view)

LevelApprox. recoverable areaMeaning
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):

ItemBehavior on this site
PipelineFileReader → Image → canvas.drawImage → getImageData → jsQR(data, width, height)
Library optionsNo options object (jsQR defaults)
PreprocessingOn failure, tries original → grayscale → invert → grayscale+invert; no descreen / perspective fix
Inputaccept="image/*"; file picker, drag-and-drop, clipboard paste
OutputDecoded text plus preview only—UI does not show version/location
PrivacyFully 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

  1. Read codes on cards, posters, packaging
  2. Preview URLs before opening (cheap safety habit)
  3. Extract text, Wi‑Fi strings, vCards
  4. Debug your own generated codes
  5. Decode desktop screenshots without a phone

How to Use This Site's Decoder

  1. Open the QR code decoder
  2. Upload, drop, or paste an image
  3. Read the text and preview
  4. 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/%XX bloat → 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:

  1. Losing one finder fails most libraries;
  2. This site does not descreen or straighten—blur, strong perspective, and cropped codes fail;
  3. 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 / shapeMeaningCaution
https://…URLPhishing pages use QR as much as email links
WIFI:T:…;S:…;P:…;;Wi-Fi joinPassword in cleartext in the payload
mailto: / tel:Contact actionsEasy to mistype; confirm before share
BEGIN:VCARDContact cardMay include more PII than you expect
Opaque base64 / JWT-lookingApp-specificDecode 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.