/qr-scanner-wechat

QR Code scanner in JS with Open CV and WeChat's Algorithm

Primary LanguageJavaScriptMIT LicenseMIT

qr-scanner-wechat

NPM version

QR Code scanner for JavaScript, based on a WebAssembly build of OpenCV and WeChat QR Code Scanner. Provides a much better detection rate and error tolerance.

Ported and rewritten from leidenglai/opencv-js-qrcode for modern browser build and easier usage. Huge thanks to @leidenglai for the previous work and research.

Usage

npm i qr-scanner-wechat
import { scan } from 'qr-scanner-wechat'

const result = await scan(canvas) // Or ImageElement

Upon the first call of scan, around 2.5MB gzipped of WebAssembly and models will be loaded asynchronously.

You can also preload them with:

import { ready, scan } from 'qr-scanner-wechat'

await ready()
const result = await scan(canvas)

Stream

In case you want to scan with streams like camera inputs, here is some code snippet for reference

<video id="video">
import { scan } from 'qr-scanner-wechat'

const stream = await navigator.mediaDevices.getUserMedia({
  audio: false,
  video: {
    width: 512,
    height: 512,
  },
})

const video = document.getElementById('video')
video.srcObject = stream
video.play()

async function scanFrame() {
  const canvas = document.createElement('canvas')
  canvas.width = video.videoWidth
  canvas.height = video.videoHeight
  const ctx = canvas.getContext('2d')
  ctx.drawImage(video, 0, 0, canvas.width, canvas.height)
  const result = await scan(canvas)

  if (result?.text)
    alert(result?.text)
}

setInterval(scanFrame, 100) // scan one frame every 100ms

Node.js

It's also possible to do scanning on Node.js. To do so, you'll need some additional transformations to an ImageData-compatible format. We recommend using sharp and here is an example:

import { scan } from 'qrcode-openev-wechat'
import sharp from 'sharp'

const image = sharp('/path/to/image.png') // or Buffer, anything sharp supports

const { data, info } = await image
// .resize(1000) // you can resize first to improve the performance
  .ensureAlpha()
  .raw()
  .toBuffer({
    resolveWithObject: true,
  })

const result = await scan({
  data: Uint8ClampedArray.from(data),
  width: info.width,
  height: info.height,
})

console.log(result?.text)

Sponsors

License

MIT License © 2023 Anthony Fu