這篇文章分享下如何結合React Webcam和Dynamsoft JavaScript Barcode SDK來建立Web掃碼App。javascript
從GitHub上下載react-webcam.js放到React工程中。 打開這個JS文件。在render()
函數中添加一個button
和canvas
:css
render() { return ( <div id='videoview' width={this.props.width} height={this.props.height}> <button onClick={this.scanBarcode}>Scan Barcodes</button> <video autoPlay width={this.props.width} height={this.props.height} src={this.state.src} muted={this.props.audio} className={this.props.className} playsInline style={this.props.style} ref={(ref) => { this.video = ref; }} /> <canvas id="overlay" width={this.props.width} height={this.props.height}></canvas> </div> ); }
button
用於觸發掃碼,canva
用來繪製顯示結果。爲了讓結果顯示在video
上方,建立一個react-webcam.css
調整下佈局:html
#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文件:java
import React, { Component } from 'react'; import PropTypes from 'prop-types'; import './react-webcam.css';
建立button
的響應事件scanBarcode()
。函數觸發時,先把video
繪製到一個臨時canvas
上。而後獲得圖像數據傳入barcode解碼接口中:react
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
點擊的時候沒法使用:git
constructor() { super(); this.state = { hasUserMedia: false, }; this.scanBarcode = this.scanBarcode.bind(this); }
掃描觸發以後須要持續調用scanBarcode()
,並把結果顯示在video
上:github
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
:web
<body> <img src="loading.gif" style="margin-top:10px" id="anim-loading"> <script src="https://demo.dynamsoft.com/dbr_wasm/js/dbr-6.4.1.3.min.js"></script> <script> dynamsoft.dbrEnv.resourcesPath = 'https://demo.dynamsoft.com/dbr_wasm/js'; dynamsoft.dbrEnv.onAutoLoadWasmSuccess = function () { window.reader = new dynamsoft.BarcodeReader(); window.dynamsoft = dynamsoft; document.getElementById('anim-loading').style.display = 'none'; }; dynamsoft.dbrEnv.onAutoLoadWasmError = function (ex) { document.getElementById('anim-loading').style.display = 'none'; alert('Fail to load the wasm file.'); }; dynamsoft.dbrEnv.bUseWorker = true; // Get a free trial license from https://www.dynamsoft.com/CustomerPortal/Portal/TrialLicense.aspx dynamsoft.dbrEnv.licenseKey = "Your Barcode SDK License" </script> <div id="root"></div>
這裏必須把dynamsoft.dbrEnv.bUseWorker
設置成true
。只有使用了web worker
,主線程纔不會由於條形碼識別耗時而卡住。npm
在App.js
中添加React Webcam
:canvas
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 ( <div className="App"> <Barcode/> <Webcam /> </div> ); } } export default App;
運行程序:
npm start
在瀏覽器中訪問localhost:3000
:
https://github.com/dynamsoft-dbr/javascript-barcode/tree/master/examples/react-wasm-barcode