From 93134cd9cd9130367ab4a665a8c6aa58a2eaa2de Mon Sep 17 00:00:00 2001 From: Christoph Reiter <reiter.christoph@gmail.com> Date: Thu, 22 Oct 2020 13:50:10 +0200 Subject: [PATCH] Add qr-scanner as an alternative backend --- packages/qr-code-scanner/rollup.config.js | 1 + .../qr-code-scanner/src/qr-code-scanner.js | 47 +++++++++++++++++-- 2 files changed, 43 insertions(+), 5 deletions(-) diff --git a/packages/qr-code-scanner/rollup.config.js b/packages/qr-code-scanner/rollup.config.js index 83266356..c0dbd55c 100644 --- a/packages/qr-code-scanner/rollup.config.js +++ b/packages/qr-code-scanner/rollup.config.js @@ -72,6 +72,7 @@ export default (async () => { {src: 'assets/index.html', dest: 'dist'}, {src: 'assets/favicon.ico', dest: 'dist'}, {src: await getPackagePath('dbp-common', 'assets/icons/*.svg'), dest: 'dist/local/dbp-common/icons'}, + {src: await getPackagePath('qr-scanner', 'qr-scanner-worker.*'), dest: 'dist/local/qr-code-scanner'}, ] }), (process.env.ROLLUP_WATCH === 'true') ? serve({ diff --git a/packages/qr-code-scanner/src/qr-code-scanner.js b/packages/qr-code-scanner/src/qr-code-scanner.js index f8504b21..5b7e42f2 100644 --- a/packages/qr-code-scanner/src/qr-code-scanner.js +++ b/packages/qr-code-scanner/src/qr-code-scanner.js @@ -5,9 +5,11 @@ import * as commonStyles from 'dbp-common/styles'; import {ScopedElementsMixin} from '@open-wc/scoped-elements'; import {Icon, MiniSpinner} from 'dbp-common'; import {classMap} from 'lit-html/directives/class-map.js'; +import * as commonUtils from 'dbp-common/utils'; import jsQR from "jsqr"; import {getIconSVGURL} from 'dbp-common'; import {Mutex} from 'async-mutex'; +import QrScanner from 'qr-scanner'; /** @@ -98,6 +100,42 @@ async function createVideoElement(deviceId) { } +class jsQRScanner { // eslint-disable-line no-unused-vars + constructor() { + } + + async scan(canvas, x, y, width, height) { + let imageData = canvas.getContext("2d").getImageData(x, y, width, height); + const code = jsQR(imageData.data, imageData.width, imageData.height, { + inversionAttempts: "dontInvert", + }); + if (code === null) + return null; + return {'data': code.data}; + } +} + + +class QRScanner { + constructor() { + QrScanner.WORKER_PATH = commonUtils.getAssetURL('qr-code-scanner', 'qr-scanner-worker.min.js'); + this._engine = null; + this._canvas = document.createElement("canvas"); + } + + async scan(canvas, x, y, width, height) { + if (this._engine === null) { + this._engine = await QrScanner.createQrEngine(QrScanner.WORKER_PATH); + } + try { + return {data: await QrScanner.scanImage(canvas, {x: x, y: y, width: width, height: height}, this._engine, this._canvas)}; + } catch (e) { + return null; + } + } +} + + export class QrCodeScanner extends ScopedElementsMixin(DBPLitElement) { constructor() { super(); @@ -214,7 +252,9 @@ export class QrCodeScanner extends ScopedElementsMixin(DBPLitElement) { let lastCode = null; let lastSentData = null; - const tick = () => { + let detector = new QRScanner(); + + const tick = async () => { this._requestID = null; if (video.readyState === video.HAVE_ENOUGH_DATA) { this._loading = false; @@ -242,10 +282,7 @@ export class QrCodeScanner extends ScopedElementsMixin(DBPLitElement) { let shouldAnalyze = Math.abs(lastVideoScanTime - video.currentTime) >= 1/3; if (shouldAnalyze) { lastVideoScanTime = video.currentTime; - let imageData = canvas.getImageData(maskStartX, maskStartY, maskWidth, maskHeight); - code = jsQR(imageData.data, imageData.width, imageData.height, { - inversionAttempts: "dontInvert", - }); + code = await detector.scan(canvasElement, maskStartX, maskStartY, maskWidth, maskHeight); lastCode = code; } else { code = lastCode; -- GitLab