Сканер QR-кода Javascript, основанный на javascript-порте Космо Вульфа библиотеки Google ZXing.
В этой библиотеке по сравнению с исходным портом было применено несколько улучшений:
BarcodeDetector
, загружается только ~15,3 КБ (~5,6 КБ в сжатом виде gzip).Согласно нашим тестам, скорость обнаружения механизма сканера этого проекта примерно в 2-3 раза (и до 8 раз) выше, чем у одной из самых популярных библиотек QR-сканеров Javascript LazarSoft/jsqrcode. Кроме того, другая библиотека часто неправильно считывает содержимое QR-кодов, в то время как в этом проекте при тестировании не было выявлено ошибок в чтении.
Библиотека поддерживает сканирование непрерывного видеопотока с веб-камеры, а также сканирование отдельных изображений.
Разработку этой библиотеки спонсирует 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
на свой дистрибутив, рядом с 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
непосредственно с вашим немодульным кодом с помощью таких инструментов, как gulp или grunt.require
таких как браузерифи: 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 , либо режим обращения, указанный как '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 может быть предоставлен как опция overlay , см. ниже, или доступен через qrScanner.$overlay . SVG можно свободно стилизовать с помощью CSS, например, задав цвет заливки, цвет обводки, ширину обводки и т. д. Примеры см. в демо. Для более особых нужд вы также можете напрямую использовать cornerPoints , см. ниже, для самостоятельной визуализации контура или точек. |
overlay | Пользовательский div , который можно предоставить для использования с highlightScanRegion и highlightCodeOutline . div должен быть родственным по отношению к videoElem в DOM. Если указана эта опция, стили по умолчанию для 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, File/Blob, URI данных, URL-адреса, указывающие на изображение (если они находятся в одном источнике или включены CORS).
В качестве необязательного второго параметра может быть предоставлен объект options. Поддерживаемые параметры:
Вариант | Описание |
---|---|
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
. Это может быть полезно, поскольку позволяет пользователю выбрать конкретную камеру для использования.
При желании вы можете запросить метки камеры. Обратите внимание, что для этого, однако, требуется разрешение пользователя на доступ к камерам, которое ему будет предложено, если оно еще не предоставлено. Если специально не запрошено, метки устройств определяются в максимально возможном порядке, т. е. возвращаются фактические метки, если разрешения уже были предоставлены, и резервные метки в противном случае. Если вы хотите запросить метки камер, рекомендуется вызывать listCameras
после успешного запуска экземпляра QrScanner, поскольку к тому времени пользователь уже даст свое разрешение.
QrScanner . listCameras ( ) ; // async; without requesting camera labels
QrScanner . listCameras ( true ) ; // async; requesting camera labels, potentially asking the user for permission
Вы можете изменить предпочитаемую камеру. Предпочтением может быть либо идентификатор устройства, возвращаемый listCameras
, либо режим обращения, указанный как '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 ) ;
Где red
, green
и blue
должны в сумме составлять 256, если useIntegerApproximation === true
, и 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-сканер выйдет из строя после его уничтожения.
Проект предварительно собран в qr-scanner.min.js в сочетании с qr-scanner-worker.min.js. Самостоятельная сборка необходима только в том случае, если вы хотите изменить код в папке /src. Для сборки требуется NodeJs.
Установите необходимые пакеты сборки:
yarn
Здание:
yarn build