这篇文章分享下如何结合和来创建Web扫码App。
Web实时扫码
从GitHub上下载放到React工程中。 打开这个JS文件。在render()
函数中添加一个button
和canvas
:
render() { return (); }
button
用于触发扫码,canva
用来绘制显示结果。为了让结果显示在video
上方,创建一个react-webcam.css
调整下布局:
#videoview { position: relative; width: 640px; height: 480px; } #video { position: relative; width: 100%; height: 100%; z-index: 1} #overlay { position: absolute; top: 100; left: 0; width: 100%; height: 100%; z-index: 2}
在react-webcam.js
中导入这个CSS文件:
import React, { Component } from 'react';import PropTypes from 'prop-types';import './react-webcam.css';
创建button
的响应事件scanBarcode()
。函数触发时,先把video
绘制到一个临时canvas
上。然后得到图像数据传入barcode解码接口中:
scanBarcode() { if (window.reader) { let canvas = document.createElement('canvas'); canvas.width = this.props.width; canvas.height = this.props.height let ctx = canvas.getContext('2d'); ctx.drawImage(this.video, 0, 0, this.props.width, this.props.height); window.reader.decodeBuffer( ctx.getImageData(0, 0, canvas.width, canvas.height).data, canvas.width, canvas.height, canvas.width * 4, window.dynamsoft.BarcodeReader.EnumImagePixelFormat.IPF_ARGB_8888 ) .then((results) => { this.showResults(results); }); } }
构造函数中需要绑定this
。如果不绑定,this
在button
点击的时候无法使用:
constructor() { super(); this.state = { hasUserMedia: false, }; this.scanBarcode = this.scanBarcode.bind(this); }
扫描触发之后需要持续调用scanBarcode()
,并把结果显示在video
上:
showResults(results) { let context = this.clearOverlay(); let txts = []; try { let localization; for (var i = 0; i < results.length; ++i) { if (results[i].LocalizationResult.ExtendedResultArray[0].Confidence >= 30) { txts.push(results[i].BarcodeText); localization = results[i].LocalizationResult; this.drawResult(context, localization, results[i].BarcodeText); } } this.scanBarcode(); } catch (e) { this.scanBarcode(); } } clearOverlay() { let context = document.getElementById('overlay').getContext('2d'); context.clearRect(0, 0, this.props.width, this.props.height); context.strokeStyle = '#ff0000'; context.lineWidth = 5; return context; } drawResult(context, localization, text) { context.beginPath(); context.moveTo(localization.X1, localization.Y1); context.lineTo(localization.X2, localization.Y2); context.lineTo(localization.X3, localization.Y3); context.lineTo(localization.X4, localization.Y4); context.lineTo(localization.X1, localization.Y1); context.stroke(); context.font = '18px Verdana'; context.fillStyle = '#ff0000'; let x = [ localization.X1, localization.X2, localization.X3, localization.X4 ]; let y = [ localization.Y1, localization.Y2, localization.Y3, localization.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]; context.fillText(text, left, top + 50); }
在public/index.html
中加载dbr-6.4.1.3.min.js
文件,并创建可用于全局访问的window.reader
:
这里必须把dynamsoft.dbrEnv.bUseWorker
设置成true
。只有使用了web worker
,主线程才不会因为条形码识别耗时而卡住。
在App.js
中添加React Webcam
:
import React, { Component } from 'react';import logo from './logo.svg';import './App.css';import {Barcode} from './Barcode';import Webcam from './react-webcam'; class App extends Component { render() { return (); }} export default App;
运行程序:
npm start
在浏览器中访问localhost:3000
: