在上一篇文章中,我们谈到了如何在Web前端应用中控制摄像头变焦。在本文中,我们将编写一个Web扫码应用,并添加自动控制摄像头变焦以扫描远处微小二维码的功能。
使用Dynamsoft Barcode Reader读取二维码,检测视频流中是否有二维码。
演示视频:
编写一个Web扫码应用
首先,让我们创建一个Web扫码应用。
-
创建一个包含以下模板的新HTML文件。
<!DOCTYPE html> <html> <head> <title>QR Code Scanner with Auto-Zoom</title> <meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=0" /> <style> #enhancerUIContainer { height: 480px; max-width: 100%; } .results { border: 1px black solid; margin: 10px 0; padding: 5px; height: 75px; overflow: auto; } </style> </head> <body> <h2>QR Code Scanner with Auto-Zoom</h2> <label> Camera: <select id="select-camera"></select> </label> <label> Resolution: <select id="select-resolution"> <option value="640x480">640x480</option> <option value="1280x720">1280x720</option> <option value="1920x1080" selected>1920x1080</option> <option value="3840x2160">3840x2160</option> </select> </label> <button onclick="startCamera();">Start Camera</button> <br/> <div class="results"> <div>Results:</div> <ol></ol> </div> <div id="enhancerUIContainer"></div> <script type="text/javascript"> </script> </body> </html>
-
在head引入所需的库。
<script src="https://cdn.jsdelivr.net/npm/dynamsoft-core@3.2.10/dist/core.js"></script> <script src="https://cdn.jsdelivr.net/npm/dynamsoft-license@3.2.10/dist/license.js"></script> <script src="https://cdn.jsdelivr.net/npm/dynamsoft-utility@1.2.10/dist/utility.js"></script> <script src="https://cdn.jsdelivr.net/npm/dynamsoft-barcode-reader@10.2.10/dist/dbr.js"></script> <script src="https://cdn.jsdelivr.net/npm/dynamsoft-capture-vision-router@2.2.10/dist/cvr.js"></script> <script src="https://cdn.jsdelivr.net/npm/dynamsoft-camera-enhancer@4.0.2/dist/dce.js"></script>
-
初始化许可证以使用Dynamsoft的SDK。可以在此处申请许可证。
let license = "DLS2eyJoYW5kc2hha2VDb2RlIjoiMjAwMDAxLTE2NDk4Mjk3OTI2MzUiLCJvcmdhbml6YXRpb25JRCI6IjIwMDAwMSIsInNlc3Npb25QYXNzd29yZCI6IndTcGR6Vm05WDJrcEQ5YUoifQ=="; //one-day trial license Dynamsoft.License.LicenseManager.initLicense(license);
-
初始化用于控制摄像头的Dynamsoft Camera Enhancer。
let cameraView = await Dynamsoft.DCE.CameraView.createInstance(); cameraEnhancer = await Dynamsoft.DCE.CameraEnhancer.createInstance(cameraView); document.querySelector("#enhancerUIContainer").append(cameraView.getUIElement());
-
创建一个capture vision router实例,以调用Dynamsoft Barcode Reader。
Dynamsoft.Core.CoreModule.loadWasm(["dbr"]); router = await Dynamsoft.CVR.CaptureVisionRouter.createInstance();
-
将camera enhancer设置为capture vision router的输入源。capture vision router将尝试获取视频帧并读码。此外,还设置了一个过滤器,以便根据多个帧的扫码结果进行验证以及避免过快返回重复的码值。
router.setInput(cameraEnhancer); router.addResultReceiver({ onDecodedBarcodesReceived: (result) => { displayResults(result); }}); let filter = new Dynamsoft.Utility.MultiFrameResultCrossFilter(); filter.enableResultCrossVerification("barcode", true); filter.enableResultDeduplication("barcode", true); await router.addResultFilter(filter);
-
启动所选摄像头,并在摄像头打开后开始读码。
async function startCamera(){ let selectedCamera = cameras[document.getElementById("select-camera").selectedIndex]; let selectedResolution = document.getElementById("select-resolution").selectedOptions[0].value; let width = parseInt(selectedResolution.split("x")[0]); let height = parseInt(selectedResolution.split("x")[1]); await cameraEnhancer.selectCamera(selectedCamera); await cameraEnhancer.setResolution({width:width, height:height}); await cameraEnhancer.open(); await router.startCapturing("ReadSingleBarcode"); }
结果将显示在一个容器中。
function displayResults(result){ if (result.barcodeResultItems.length > 0) { let ol = document.querySelector(".results ol"); ol.innerHTML = ""; for (let index = 0; index < result.barcodeResultItems.length; index++) { const item = result.barcodeResultItems[index]; const li = document.createElement("li"); li.innerText = item.formatString+": "+item.text; ol.appendChild(li); } } }
启用自动变焦
Web扫码应用编写完成后,我们可以添加自动变焦功能,以改善微小或远距离二维码的扫描。如果视频流中有无法读取的二维码,则触发自动变焦。变焦后,如果无法在几秒钟内读取二维码,将返回默认缩放状态。
该功能包含在Dynamsoft Camera Enhancer中。我们可以使用以下代码启用它:
await cameraEnhancer.enableEnhancedFeatures(Dynamsoft.DCE.EnumEnhancedFeatures.EF_AUTO_ZOOM);
自动变焦的工作原理
那么,自动变焦究竟是如何工作的呢?
如果检测到二维码,但因为太小,无法读取,我们可以触发变焦,以获得更好的二维码图像进行读取。Dynamsoft Barcode Reader的中间结果功能可以用于获取不能被解码,但能被定位到的二维码的位置。
以下是获取位置的代码:
const intermediateResultManager = router.getIntermediateResultManager();
const intermediateResultReceiver = new Dynamsoft.CVR.IntermediateResultReceiver();
intermediateResultReceiver.onLocalizedBarcodesReceived = (result, info) => {
console.log(result);
};
intermediateResultManager.addResultReceiver(intermediateResultReceiver);
然后,我们可以计算变焦系数,以最大化视频流中的二维码图像。
function calculatedFactor(localizedBarcode){
let left = localizedBarcode.location.points[0].x;
let top = localizedBarcode.location.points[0].y;
let video = document.getElementById("video");
let width = video.videoWidth;
if (left < width/2) {
let croppedWidth = Math.max(0,left - 50);
if (croppedWidth == 0) {
return 1.0;
}
let maxCroppedWidth = top;
croppedWidth = Math.min(maxCroppedWidth,croppedWidth);
return width / (width - (croppedWidth * 2));
}else{
return 1.0;
}
}
源代码
欢迎下载源代码并尝试使用:
https://github.com/tony-xlh/Vanilla-JS-Barcode-Reader-Demos/tree/main/autozoom