如何使用JavaScript中的网络摄像头创建实时条形码扫描仪

本文概述

  • 什么是QuaggaJS
  • 安装
  • 用法
  • 例子
条形码是以数字或可变宽度的平行线的形式的形式的机器可读代码。它们用于识别产品。条形码系统可帮助企业和组织在计算机软件系统中跟踪产品和价格以进行集中管理, 从而极大地提高了生产率和效率。早在很久以前, 超市, 大卖场和其他百货商店就使用条形码扫描仪, 这些扫描仪集成在复杂的设备或系统中, 使卖方可以轻松地扫描产品。但是, 这种系统通常很复杂, 而且价格不菲。
如果你是与某公司(或与某大公司)合作的Web开发人员, 出于某种原因, 要么出售某物, 要么仅仅是因为可以使用这种工具轻松检索系统生成的文档的某些信息, 那么, 你可以在你的应用中实现此功能, 并将其提供给客户。如果他们知道他们不需要购买额外的设备来扫描代码, 而只用他们的网络摄像头就能同时实现相同的质量, 那么他们肯定会很高兴。
在本文中, 我们将向你展示如何使用Web应用程序中超棒的QuaggaJS库使用JavaScript创建实时条形码扫描仪。
什么是QuaggaJSQuaggaJS是完全用JavaScript编写的条形码扫描器, 支持实时定位和解码各种类型的条形码, 例如EAN, CODE 128, CODE 39, EAN 8, UPC-A, UPC-C, I2of5和CODABAR。该库还能够使用getUserMedia直接访问用户的相机流。尽管该代码依赖大量的图像处理, 但即使是最近的智能手机也能够实时定位和解码条形码。 QuaggaJS是zxing库的修改版本, 可简化用户的条形码扫描过程。简而言之, 此阅读器的缩放和旋转不变, 而其他库要求条形码与视口对齐。这不是伟大的zxing库的另一个移植, 而是更多的扩展。该实现的特征在于条形码定位器, 该条形码定位器能够在图像中找到类似条形码的图案, 从而产生包括旋转在内的估计边界框。
Quagga利用了许多现代Web-API, 但尚未被所有浏览器实现。 Quagga的运行模式有两种:
  1. 分析静态图片(通过Blob)。
  2. 使用相机从实时流中解码图像(要求存在MediaDevices API)。
没错, 你也可以将quaggaJS直接用于图像。
安装【如何使用JavaScript中的网络摄像头创建实时条形码扫描仪】如果使用软件包管理器, 则可以使用NPM在项目中轻松安装Quagga:
npm install quagga

或凉亭:
bower install quagga

另外, 你只需下载quagga.min.js并将其包含在你的项目中, 就可以开始使用了。该脚本将库显示在Quagga下的全局名称空间中:
< !-- Include quagga minified version from a local file --> < script src="http://www.srcmini.com/quagga.min.js"> < /script> < !-- Or use a CDN --> < script src="https://cdn.rawgit.com/serratus/quaggaJS/0420d5e0/dist/quagga.min.js"> < /script>

或者, 如果你将它与ES6, React, Angular等一起使用, 则可能要导入它:
import Quagga from 'quagga'; // ES6const Quagga = require('quagga').default; // Common JS (important: default)

有关此库的更多信息, 建议你在此处访问Github上的官方存储库。
用法如前所述, Quagga有两种工作方式, 将实时扫描仪与网络摄像头配合使用或处理静态图像:
实时扫描仪
为了能够使用网络摄像头进行动态扫描, 显然, 你需要一个支持navigator.getUserMedia的浏览器。首先初始化Quagg并配置LiveStream模式。设置默认配置后, 请使用Quagga.start方法启动视频流, 并开始查找和解码图像。你需要在解码器选项中设置要通过属性读取器处理的条形码的类型:
Quagga.init({inputStream : {name : "Live", type : "LiveStream", // Or '#yourElement' (optional)target: document.querySelector('#yourElement') }, decoder : {readers : ["code_128_reader"]}}, function(err) {if (err) {console.log(err); return}console.log("Initialization finished. Ready to start"); Quagga.start(); });

在文章的结尾, 你可以看到实时扫描仪的完整示例, 其中包括跟踪功能。
静态影像
如果要处理文件中的图像(用户上传到服务器或直接在浏览器中上传的图像), 可以使用Quagga进行处理。你只需要做的就是将locate选项设置为true, 并提供图像的路径(或图像的base64数据uri表示形式):
Quagga.decodeSingle({decoder: {readers: ["code_128_reader"] // List of active readers}, locate: true, // try to locate the barcode in the image// You can set the path to the image in your server// or using it's base64 data URI representation data:image/jpg; base64, + datasrc: '/barcode_image.jpg'}, function(result){if(result.codeResult) {console.log("result", result.codeResult.code); } else {console.log("not detected"); }});

尽管我们以最简单的表达方式总结了这两个功能, 但值得阅读文档以检查可以实现的更有趣的功能。
例子以下文档显示了一个非常简单的实现, 该实现将在扫描仪-容器div上显示扫描仪, 并在其上跟踪条形码扫描仪。处理了有效的条形码后, 它将在控制台中(在检测到的画布上)显示其结果:
< !DOCTYPE html> < html lang="en"> < head> < title> < /title> < meta charset="UTF-8"> < meta name="viewport" content="width=device-width, initial-scale=1"> < style> /* In order to place the tracking correctly */canvas.drawing, canvas.drawingBuffer {position: absolute; left: 0; top: 0; }< /style> < /head> < body> < !-- Div to show the scanner --> < div id="scanner-container"> < /div> < input type="button" id="btn" value="http://www.srcmini.com/Start/Stop the scanner" /> < !-- Include the image-diff library --> < script src="http://www.srcmini.com/quagga.min.js"> < /script> < script> var _scannerIsRunning = false; function startScanner() {Quagga.init({inputStream: {name: "Live", type: "LiveStream", target: document.querySelector('#scanner-container'), constraints: {width: 480, height: 320, facingMode: "environment"}, }, decoder: {readers: ["code_128_reader", "ean_reader", "ean_8_reader", "code_39_reader", "code_39_vin_reader", "codabar_reader", "upc_reader", "upc_e_reader", "i2of5_reader"], debug: {showCanvas: true, showPatches: true, showFoundPatches: true, showSkeleton: true, showLabels: true, showPatchLabels: true, showRemainingPatchLabels: true, boxFromPatches: {showTransformed: true, showTransformedBox: true, showBB: true}}}, }, function (err) {if (err) {console.log(err); return}console.log("Initialization finished. Ready to start"); Quagga.start(); // Set flag to is running_scannerIsRunning = true; }); Quagga.onProcessed(function (result) {var drawingCtx = Quagga.canvas.ctx.overlay, drawingCanvas = Quagga.canvas.dom.overlay; if (result) {if (result.boxes) {drawingCtx.clearRect(0, 0, parseInt(drawingCanvas.getAttribute("width")), parseInt(drawingCanvas.getAttribute("height"))); result.boxes.filter(function (box) {return box !== result.box; }).forEach(function (box) {Quagga.ImageDebug.drawPath(box, { x: 0, y: 1 }, drawingCtx, { color: "green", lineWidth: 2 }); }); }if (result.box) {Quagga.ImageDebug.drawPath(result.box, { x: 0, y: 1 }, drawingCtx, { color: "#00F", lineWidth: 2 }); }if (result.codeResult & & result.codeResult.code) {Quagga.ImageDebug.drawPath(result.line, { x: 'x', y: 'y' }, drawingCtx, { color: 'red', lineWidth: 3 }); }}}); Quagga.onDetected(function (result) {console.log("Barcode detected and processed : [" + result.codeResult.code + "]", result); }); }// Start/stop scannerdocument.getElementById("btn").addEventListener("click", function () {if (_scannerIsRunning) {Quagga.stop(); } else {startScanner(); }}, false); < /script> < /body> < /html>

编码愉快!

    推荐阅读