Javascript QR 码扫描器基于 Cosmo Wolfe 的 Google ZXing 库的 javascript 端口。
在此库中,对原始端口进行了多项改进:
BarcodeDetector
可用,则仅加载约 15.3 kB(gzip 后约 5.6 kB)。根据我们的基准测试,该项目的扫描仪引擎的检测率大约是最流行的 javascript QR 扫描仪库 LazarSoft/jsqrcode 之一的 2-3 倍(最高可达 8 倍)。另外,其他库经常误读二维码内容,而本项目在基准测试中没有出现误读情况。
该库支持扫描来自网络摄像头的连续视频流以及扫描单个图像。
该库的开发由世界上第一个基于浏览器的区块链 nimiq 赞助。
请参阅 https://nimiq.github.io/qr-scanner/demo/
通过 npm 安装:
npm install --save qr-scanner
通过纱线安装:
yarn add qr-scanner
或者只需将qr-scanner.min.js
和qr-scanner-worker.min.js
复制到您的项目中。
QR 扫描仪由两个主要文件组成。 qr-scanner.min.js
是主要 API 文件,仅在需要时通过动态导入加载工作脚本qr-scanner-worker.min.js
。如果您没有使用像 Rollup 或 Webpack 这样自动处理动态导入的打包程序,您可能需要将qr-scanner-worker.min.js
复制到您的 dist,位于qr-scanner.min.js
或脚本旁边您将qr-scanner.min.js
捆绑到其中。
qr-scanner.min.js
是一个 es6 模块,可以按如下方式导入:
import QrScanner from 'path/to/qr-scanner.min.js' ; // if using plain es6 import
import QrScanner from 'qr-scanner' ; // if installed via package and bundling with a module bundler like webpack or rollup
这要求导入脚本也是 es6 模块或模块脚本标签,例如:
< script type =" module " >
import QrScanner from 'path/to/qr-scanner.min.js' ;
// do something with QrScanner
</ script >
如果您的项目不是基于 es6 模块,您可以
import ( 'path/to/qr-scanner.min.js' ) . then ( ( module ) => {
const QrScanner = module . default ;
// do something with QrScanner
} ) ;
qr-scanner.umd.min.js
直接用作非模块脚本 < script src =" path/to/qr-scanner.umd.min.js " > </ script >
< script >
// do something with QrScanner
</ script >
qr-scanner.umd.min.js
直接与非模块代码捆绑在一起。require
的捆绑器(如 browserify)捆绑在一起: const QrScanner = require ( 'qr-scanner' ) ; // if installed via package
const QrScanner = require ( 'path/to/qr-scanner.umd.min.js' ) ; // if not installed via package
// do something with QrScanner
该库使用 ECMAScript 2017 功能,例如async
函数。如果您需要支持旧浏览器,可以使用qr-scanner.legacy.min.js
,它与 ECMAScript 2015 (ES6) 兼容。它是 UMD 版本,可以用作qr-scanner.umd.min.js
的替代品,请参见上文。请注意,旧版本更大,因为它包含一些填充,并且为了支持不支持动态导入的浏览器,内联了工作脚本,但无论如何都需要在旧浏览器中加载该脚本。不过,您可能不需要使用旧版本,因为一般浏览器支持对于常规版本来说已经非常好。特别是如果您想从设备的相机进行扫描,浏览器对相机的支持是更严格的限制。
创建一个<video>
元素,应在其中渲染网络摄像头视频流:
< video > </ video >
// To enforce the use of the new api with detailed scan results, call the constructor with an options object, see below.
const qrScanner = new QrScanner (
videoElem ,
result => console . log ( 'decoded qr code:' , result ) ,
{ /* your options or returnDetailedScanResult: true if you're not specifying any other options */ } ,
) ;
// For backwards compatibility, omitting the options object will currently use the old api, returning scan results as
// simple strings. This old api will be removed in the next major release, by which point the options object is then
// also not required anymore to enable the new api.
const qrScanner = new QrScanner (
videoElem ,
result => console . log ( 'decoded qr code:' , result ) ,
// No options provided. This will use the old api and is deprecated in the current version until next major version.
) ;
可以提供选项对象作为可选的第三个参数。支持的选项有:
选项 | 描述 |
---|---|
onDecodeError | 解码错误时调用的处理程序。默认为QrScanner._onDecodeError 。 |
preferredCamera | 对要使用的相机的偏好。首选项可以是listCameras 返回的设备 ID,也可以是指定为'environment' 或'user' 面向模式。默认为'environment' 。请注意,不能保证该偏好实际上可以得到满足。 |
maxScansPerSecond | 此选项可用于限制扫描以减少电池消耗。默认值为 25。如果浏览器支持,扫描速率永远不会高于相机的帧速率,以避免同一帧上不必要的重复扫描。 |
calculateScanRegion | 一种确定应限制扫描的区域以提高性能的方法。作为额外的性能改进,在执行扫描之前也可以选择缩小该区域。该区域被指定为x 、 y 、 width 和height ;缩小区域的尺寸为downScaledWidth 和downScaledHeight 。请注意, width 和height 以及downScaledWidth 和downScaledHeight 之间的长宽比应保持相同。默认情况下,扫描区域限制为视频宽度或高度的三分之二(以较小者为准)的中心正方形,并缩小至 400x400 正方形。 |
highlightScanRegion | 将此选项设置为true 可在视频流上的扫描区域周围渲染轮廓。这使用了覆盖扫描区域的绝对定位的div 。该div 可以作为选项overlay 提供(见下文),也可以自动创建然后通过qrScanner.$overlay 访问。它可以通过 CSS 自由设置样式,例如通过设置轮廓、边框、背景颜色等。请参阅演示示例。 |
highlightCodeOutline | 将此选项设置为true 可在检测到的 QR 码周围呈现轮廓。这使用了一个绝对定位的div ,用于渲染轮廓的 SVG 将放置在该 div 上。该div 可以作为选项overlay 提供,见下文,或者通过qrScanner.$overlay 访问。 SVG 可以通过 CSS 自由设置样式,例如通过设置填充颜色、描边颜色、描边宽度等。请参阅演示示例。对于更特殊的需求,您还可以直接使用cornerPoints (见下文)来自己渲染轮廓或点。 |
overlay | 可以提供用于highlightScanRegion 和highlightCodeOutline 的自定义div 。 div 应该是 DOM 中videoElem 的同级。如果提供此选项,则不会应用highlightCodeOutline 的默认样式,因为预期该元素已经应用了一些自定义样式。 |
returnDetailedScanResult | 强制报告详细的扫描结果,请参见下文。 |
要使用选项的默认值,请忽略它或提供undefined
。
传递给回调的结果取决于是否提供了选项对象:
data
(读取的 QR 码的字符串内容)和cornerPoints
(读取的 QR 码轮廓在相机流上的角点)的对象。为了避免在不提供任何其他选项的情况下使用已弃用的 api,您可以提供{ returnDetailedScanResult: true }
来启用新 api 并获取详细的扫描结果。
qrScanner . start ( ) ;
当您准备好扫描时调用它,例如单击按钮或直接在页面加载时。它将提示用户获得使用相机的许可。注意:要从网络摄像头流中读取数据,您的页面必须通过 HTTPS 提供服务。
qrScanner . stop ( ) ;
如果需要,您可以随时停止扫描并通过再次调用start()
来恢复扫描。
QrScanner . scanImage ( image )
. then ( result => console . log ( result ) )
. catch ( error => console . log ( error || 'No QR code found.' ) ) ;
支持的图像源有:HTMLImageElement、SVGImageElement、HTMLVideoElement、HTMLCanvasElement、ImageBitmap、OffscreenCanvas、文件/Blob、数据 URI、指向图像的 URL(如果它们位于同一源或启用了 CORS)
可以提供选项对象作为可选的第二个参数。支持的选项有:
选项 | 描述 |
---|---|
scanRegion | 由x 、 y 、 width 和height 定义的区域,应限制 QR 码的搜索。作为性能改进,可以通过提供downScaledWidth 和downScaledHeight 在执行扫描之前缩小该区域。请注意, width 和height 以及downScaledWidth 和downScaledHeight 之间的长宽比应保持相同。默认情况下,该区域跨越整个图像并且不会缩小。 |
qrEngine | 手动创建的可重复使用的 QR 扫描仪引擎实例。如果您扫描大量图像,这可以提高性能。可以通过QrScanner.createQrEngine(QrScanner.WORKER_PATH) 手动创建引擎。默认情况下,单个图像扫描不会重复使用任何引擎。 |
canvas | 手动创建的可重复使用的画布。如果您扫描大量图像,这可以提高性能。可以通过标记中的<canvas> 标记或document.createElement('canvas') 手动创建画布。默认情况下,单个图像扫描不会重复使用画布。 |
disallowCanvasResizing | 请求提供的画布以供重复使用,无论源图像或源区域尺寸如何,都不会调整大小。请注意,画布和源区域应具有相同的纵横比,以避免要扫描的图像变形,从而导致无法检测 QR 码。默认情况下,画布大小会适应扫描区域尺寸或缩小的扫描区域以进行单图像扫描。 |
alsoTryWithoutScanRegion | 如果提供了scanRegion 并且在该区域内未找到 QR 代码,则请求对整个图像进行第二次扫描。默认情况下,不会尝试进行第二次扫描。 |
returnDetailedScanResult | 强制报告详细的扫描结果,请参见下文。 |
要使用选项的默认值,请忽略它或提供undefined
。
返回的结果取决于是否提供了选项对象:
data
(读取的 QR 码的字符串内容)和cornerPoints
(读取的 QR 码轮廓在相机流上的角点)的对象。为了避免在不提供任何其他选项的情况下使用已弃用的 api,您可以提供{ returnDetailedScanResult: true }
来启用新 api 并获取详细的扫描结果。
如果无法读取 QR 码,则scanImage
抛出异常。
该库提供了一种用于检查设备是否有摄像头的实用方法。这对于确定是否向用户提供 QR 网络摄像头扫描功能非常有用。
QrScanner . hasCamera ( ) ; // async
该库提供了一种实用方法,用于获取设备摄像头列表,通过其id
和label
定义。这对于让用户选择要使用的特定相机很有用。
您可以选择请求相机的标签。但请注意,这需要用户获得访问摄像头的许可,如果尚未获得许可,系统会要求用户授予该许可。如果没有特别请求,设备标签将尽力确定,即,如果已授予权限,则返回实际标签,否则返回后备标签。如果您想请求相机标签,建议在 QrScanner 实例成功启动后调用listCameras
,因为此时用户已经授予了他的权限。
QrScanner . listCameras ( ) ; // async; without requesting camera labels
QrScanner . listCameras ( true ) ; // async; requesting camera labels, potentially asking the user for permission
您可以更改要使用的首选相机。首选项可以是listCameras
返回的设备 ID,也可以是指定为'environment'
或'user'
面向模式。请注意,不能保证该偏好实际上可以得到满足。
qrScanner . setCamera ( facingModeOrDeviceId ) ; // async
默认情况下,扫描仪会在明亮的背景上扫描深色 QR 码。您可以更改此行为以扫描深色背景上的明亮 QR 码或同时扫描两者:
qrScanner . setInversionMode ( inversionMode ) ;
其中inversionMode
可以是original
、 invert
或both
兼而有之。网络摄像头扫描的默认值为original
,单图像扫描的默认值为原始both
。
更改灰度计算中红色、绿色和蓝色的权重,以提高特定颜色 QR 码的对比度:
qrScanner . setGrayscaleWeights ( red , green , blue , useIntegerApproximation = true ) ;
如果useIntegerApproximation === true
则red
、 green
和blue
总和应为 256,否则为1
。默认情况下,使用这些值。
在支持的浏览器上,您可以检查当前使用的相机是否有闪光灯并打开或关闭它。请注意,应在扫描仪成功启动后调用 hasFlash,以避免仅为了查询是否支持闪光灯而需要打开临时相机流,从而可能要求用户访问相机。
qrScanner . hasFlash ( ) ; // check whether the browser and used camera support turning the flash on; async.
qrScanner . isFlashOn ( ) ; // check whether the flash is on
qrScanner . turnFlashOn ( ) ; // turn the flash on if supported; async
qrScanner . turnFlashOff ( ) ; // turn the flash off if supported; async
qrScanner . toggleFlash ( ) ; // toggle the flash if supported; async.
如果不再需要 QR 扫描仪,您可以销毁它:
qrScanner . destroy ( ) ;
qrScanner = null ;
这将停止摄像头流和网络工作人员并清理事件侦听器。二维码扫描仪被破坏后将无法正常工作。
该项目是在 qr-scanner.min.js 中与 qr-scanner-worker.min.js 结合预构建的。仅当您想更改 /src 文件夹中的代码时才需要自行构建。构建需要 NodeJs。
安装所需的构建包:
yarn
建筑:
yarn build