1

yushulx的个人页面

 3 years ago
source link: https://my.oschina.net/yushulx/blog/5080431
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

要在Web端实现基于摄像头的实时QR二维码扫描,需要包含摄像头控制和QR二维码解码两个部分的代码。Dynamsoft把这两部分封装在了一个JS SDK中,使用起来非常方便。

https://www.dynamsoft.com/barcode-reader/programming/javascript/api-reference/BarcodeScanner.html?ver=latest

快速创建Web QR扫描程序

我们写一个最简单的hello world程序。

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width,initial-scale=1.0">
        <title>Dynamsoft JavaScript Barcode Scanner</title>
        <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/dbr.js"></script>
    </head>
<body>
    <script>
        let scanner = null;
        (async()=>{
            scanner = await Dynamsoft.DBR.BarcodeScanner.createInstance();
            scanner.onFrameRead = results => {console.log(results);};
            scanner.onUnduplicatedRead = (txt, result) => {};
            await scanner.show();
        })();
    </script>
</body>
</html>

把代码保存到index.html中,直接双击运行就行了。

这个程序是全屏显示的,而且第一次运行的时候会弹出提示框。有7天的免费试用期。如果需要更长的30天试用期,只需要通过账号申请一个ID就可以了。接下来分享下如何优化这个程序。

隐藏提示框

这个提示框跳出来可能很不爽,通过JS代码可以去掉:

<script>
    Dynamsoft.DBR.BarcodeScanner.showDialog = function () { };
    let scanner = null;
</script>

手动加载wasm文件

因为这个SDK是基于WebAssembly的,初始化的时间会比较长一些。所以可以在web页面初始化之后再加载:

<script>
    Dynamsoft.DBR.BarcodeScanner.showDialog = function () { };
    window.onload = async function () {
        try {
            await Dynamsoft.DBR.BarcodeScanner.loadWasm();
            await initBarcodeScanner();
        } catch (ex) {
            alert(ex.message);
            throw ex;
        }
    };
    let scanner = null;
    async function initBarcodeScanner() {
        scanner = await Dynamsoft.DBR.BarcodeScanner.createInstance();
        scanner.onFrameRead = results => {console.log(results);};
        scanner.onUnduplicatedRead = (txt, result) => {};
        await scanner.show();
    }
</script>

正常使用的时候,摄像头的预览画面肯定不希望是全屏显示的。我们可以把摄像头的预览窗口放到一个DIV元素中:

<div id="barcodeScanner">
    <span id='loading-status' style='font-size:x-large'>Loading Library...</span>
</div>
<script>
    ...
    async function initBarcodeScanner() {
        scanner = await Dynamsoft.DBR.BarcodeScanner.createInstance();
        scanner.onFrameRead = results => {console.log(results);};
        scanner.onUnduplicatedRead = (txt, result) => {};
        document.getElementById('barcodeScanner').appendChild(scanner.getUIElement());
        document.getElementById('loading-status').hidden = true;
        await scanner.show();
    }
</script>

注意到默认程序的右上角有一个关闭按钮,我们可以用代码隐藏:

document.getElementsByClassName('dbrScanner-sel-camera')[0].hidden = true;

创建一个DIV元素来显示扫码结果:

<div>
    Barcode Result: <a id='result'>N/A</a>
</div>
<script>
    ...
    scanner.onFrameRead = results => {
        console.log(results);
        for (let result of results) {
            document.getElementById('result').innerHTML = result.barcodeFormatString + ", " + result.barcodeText;
        }
    };
    ...
</script>

最后用CSS调整下布局:

<style>
    body {
        display: flex;
        flex-direction: column;
        align-items: center;
    }

    #barcodeScanner {
        text-align: center;
        font-size: medium;
        height: 40vh;
        width: 40vw;
    }
</style>

现在刷新页面,程序看起来好多了。

在摄像头预览窗口上绘制识别结果

SDK默认会把码的区域绘制出来,但是没有文字结果。打开开发者控制栏查看源码。

发现_drawRegionsults函数是用来绘制结果的。我们重载这个函数,并增加文字绘制的逻辑:

...
for (let t of e) {
    let e = t.localizationResult;
    s.beginPath(),
        s.moveTo(e.x1, e.y1),
        s.lineTo(e.x2, e.y2),
        s.lineTo(e.x3, e.y3),
        s.lineTo(e.x4, e.y4),
        s.fill(),
        s.beginPath(),
        s.moveTo(e.x1, e.y1),
        s.lineTo(e.x2, e.y2),
        s.lineTo(e.x3, e.y3),
        s.lineTo(e.x4, e.y4),
        s.closePath(),
        s.stroke()

    let text = t.barcodeText;
    s.font = '18px Verdana';
    s.fillStyle = '#ff0000';
    let x = [e.x1, e.x2, e.x3, e.x4];
    let y = [e.y1, e.y2, e.y3, e.y4];
    x.sort(function (a, b) {
        return a - b;
    });
    y.sort(function (a, b) {
        return b - a;
    });
    let left = x[0];
    let top = y[0];

    s.fillText(text, left, top + 50);
}
...

再刷新下页面,体验好多了。

免费的Web端QR二维码扫描程序

如果你只是想体验Web端的QR二维码,以及其它条形码的扫描,可以在浏览器直接打开 https://demo.dynamsoft.com/barcode-reader-js/

https://github.com/yushulx/javascript-barcode-scanner


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK