Escáner de código QR Javascript basado en el puerto javascript de Cosmo Wolfe de la biblioteca ZXing de Google.
En esta biblioteca, se han aplicado varias mejoras con respecto al puerto original:
BarcodeDetector
nativo está disponible, solo se cargan ~15,3 kB (~5,6 kB comprimidos con gzip).Según nuestra evaluación comparativa, la tasa de detección del motor de escáner de este proyecto es aproximadamente 2-3 veces (y hasta 8 veces) mayor que la de la biblioteca de escáner QR de JavaScript más popular, LazarSoft/jsqrcode. Además, la otra biblioteca a menudo interpreta mal el contenido de los códigos QR, mientras que en este proyecto no se produjeron errores de lectura en la evaluación comparativa.
La biblioteca admite el escaneo de una transmisión de video continua desde una cámara web, así como el escaneo de imágenes individuales.
El desarrollo de esta biblioteca está patrocinado por nimiq, la primera cadena de bloques basada en navegador del mundo.
Ver https://nimiq.github.io/qr-scanner/demo/
Para instalar a través de npm:
npm install --save qr-scanner
Para instalar mediante hilo:
yarn add qr-scanner
O simplemente copie qr-scanner.min.js
y qr-scanner-worker.min.js
a su proyecto.
El escáner QR consta de dos archivos principales. qr-scanner.min.js
es el archivo API principal que carga el script de trabajo qr-scanner-worker.min.js
mediante una importación dinámica, solo si es necesario. Si no está utilizando un paquete como Rollup o Webpack que maneja las importaciones dinámicas automáticamente, es posible que deba copiar qr-scanner-worker.min.js
a su dist, junto a qr-scanner.min.js
o al lado del script. en el que estás agrupando qr-scanner.min.js
.
qr-scanner.min.js
es un módulo es6 y se puede importar de la siguiente manera:
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
Esto requiere que el script de importación también sea un módulo es6 o una etiqueta de script de módulo, por ejemplo:
< script type =" module " >
import QrScanner from 'path/to/qr-scanner.min.js' ;
// do something with QrScanner
</ script >
Si su proyecto no está basado en módulos es6, puede
import ( 'path/to/qr-scanner.min.js' ) . then ( ( module ) => {
const QrScanner = module . default ;
// do something with QrScanner
} ) ;
qr-scanner.umd.min.js
para uso directo como script sin módulo < script src =" path/to/qr-scanner.umd.min.js " > </ script >
< script >
// do something with QrScanner
</ script >
qr-scanner.umd.min.js
directamente con su código que no es del módulo con herramientas como gulp o grunt.require
como 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
Esta biblioteca utiliza funciones de ECMAScript 2017, como funciones async
. Si necesita admitir navegadores antiguos, puede usar qr-scanner.legacy.min.js
, que es compatible con ECMAScript 2015 (ES6). Es una compilación UMD y se puede usar como reemplazo de qr-scanner.umd.min.js
, ver arriba. Tenga en cuenta que la compilación heredada es más grande ya que incluye algunos polyfills y, para admitir navegadores que no admiten importaciones dinámicas, incluye el script de trabajo que, sin embargo, sería necesario cargar en los navegadores heredados de todos modos. Sin embargo, probablemente no necesitarás utilizar la versión heredada, ya que la compatibilidad general con el navegador ya es muy buena para la versión normal. Especialmente si desea escanear desde la cámara del dispositivo, la compatibilidad de la cámara con el navegador es la restricción más estricta.
Cree un elemento <video>
donde se debe representar la transmisión de video de la cámara web:
< 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.
) ;
Como tercer parámetro opcional se puede proporcionar un objeto de opciones. Las opciones admitidas son:
Opción | Descripción |
---|---|
onDecodeError | Controlador que se invocará en caso de errores de decodificación. El valor predeterminado es QrScanner._onDecodeError . |
preferredCamera | Preferencia de cámara a utilizar. La preferencia puede ser una identificación de dispositivo devuelta por listCameras o un modo de orientación especificado como 'environment' o 'user' . El valor predeterminado es 'environment' . Tenga en cuenta que no hay garantía de que la preferencia pueda cumplirse realmente. |
maxScansPerSecond | Esta opción se puede utilizar para acelerar los escaneos y reducir el consumo de batería. El valor predeterminado es 25. Si el navegador lo admite, la velocidad de escaneo nunca es superior a la velocidad de fotogramas de la cámara para evitar escaneos duplicados innecesarios en el mismo fotograma. |
calculateScanRegion | Un método que determina una región a la que se debe restringir el escaneo como mejora del rendimiento. Opcionalmente, esta región también se puede reducir antes de realizar el escaneo como una mejora adicional del rendimiento. La región se especifica como x , y , width y height ; las dimensiones para la región reducida como downScaledWidth y downScaledHeight . Tenga en cuenta que la relación de aspecto entre width y height y downScaledWidth y downScaledHeight debe seguir siendo la misma. De forma predeterminada, la región de escaneo está restringida a un cuadrado centrado de dos tercios del ancho o alto del video, lo que sea menor, y se reduce a un cuadrado de 400x400. |
highlightScanRegion | Establezca esta opción en true para representar un contorno alrededor de la región de escaneo en la transmisión de video. Esto utiliza un div absolutamente posicionado que cubre la región de escaneo. Este div se puede proporcionar como opción overlay , ver más abajo, o crearse automáticamente y luego accederse a través de qrScanner.$overlay . Se puede diseñar libremente a través de CSS, por ejemplo, estableciendo un contorno, borde, color de fondo, etc. Consulte la demostración para ver ejemplos. |
highlightCodeOutline | Establezca esta opción en true para representar un contorno alrededor de los códigos QR detectados. Esto utiliza un div absolutamente posicionado en el que se colocará un SVG para representar el contorno. Este div se puede proporcionar como opción overlay , ver más abajo, o se puede acceder a él a través de qrScanner.$overlay . El SVG se puede diseñar libremente a través de CSS, por ejemplo, estableciendo el color de relleno, el color del trazo, el ancho del trazo, etc. Consulte la demostración para ver ejemplos. Para necesidades más especiales, también puede utilizar los cornerPoints directamente, ver más abajo, para representar un contorno o los puntos usted mismo. |
overlay | Un div personalizado que se puede proporcionar para su uso con highlightScanRegion y highlightCodeOutline . El div debe ser hermano de videoElem en el DOM. Si se proporciona esta opción, los estilos predeterminados para highlightCodeOutline no se aplican ya que se espera que el elemento ya tenga algún estilo personalizado aplicado. |
returnDetailedScanResult | Haga cumplir la presentación de informes de resultados de análisis detallados, consulte a continuación. |
Para utilizar el valor predeterminado para una opción, omítalo o proporcione undefined
.
Los resultados pasados a la devolución de llamada dependen de si se proporcionó un objeto de opciones:
data
de propiedades que son el contenido de la cadena del código QR leído y cornerPoints
que son los puntos de las esquinas del contorno del código QR leído en la transmisión de la cámara. Para evitar el uso de la API obsoleta si no proporciona ninguna otra opción, puede proporcionar { returnDetailedScanResult: true }
para habilitar la nueva API y obtener el resultado del análisis detallado.
qrScanner . start ( ) ;
Llámelo cuando esté listo para escanear, por ejemplo, al hacer clic en un botón o directamente al cargar la página. Le pedirá permiso al usuario para usar una cámara. Nota: para leer desde una transmisión de Web Cam, su página debe ser entregada a través de HTTPS.
qrScanner . stop ( ) ;
Si lo desea, puede detener el escaneo en cualquier momento y reanudarlo llamando start()
nuevamente.
QrScanner . scanImage ( image )
. then ( result => console . log ( result ) )
. catch ( error => console . log ( error || 'No QR code found.' ) ) ;
Las fuentes de imágenes admitidas son: HTMLImageElement, SVGImageElement, HTMLVideoElement, HTMLCanvasElement, ImageBitmap, OffscreenCanvas, File/Blob, URI de datos, URL que apuntan a una imagen (si están en el mismo origen o CORS habilitado)
Como segundo parámetro opcional se puede proporcionar un objeto de opciones. Las opciones admitidas son:
Opción | Descripción |
---|---|
scanRegion | Una región definida por x , y , width y height a la que se debe restringir la búsqueda de un código QR. Como mejora del rendimiento, esta región se puede reducir antes de realizar el análisis proporcionando downScaledWidth y downScaledHeight . Tenga en cuenta que la relación de aspecto entre width y height y downScaledWidth y downScaledHeight debe seguir siendo la misma. De forma predeterminada, la región abarca toda la imagen y no se reduce. |
qrEngine | Una instancia del motor de escáner QR creada manualmente para ser reutilizada. Esto mejora el rendimiento si escanea muchas imágenes. Se puede crear un motor manualmente a través de QrScanner.createQrEngine(QrScanner.WORKER_PATH) . De forma predeterminada, no se reutiliza ningún motor para el escaneo de una sola imagen. |
canvas | Un lienzo creado manualmente para ser reutilizado. Esto mejora el rendimiento si escanea muchas imágenes. Un lienzo se puede crear manualmente mediante una etiqueta <canvas> en su marcado o document.createElement('canvas') . De forma predeterminada, no se reutiliza ningún lienzo para escanear una sola imagen. |
disallowCanvasResizing | Solicite que no se cambie el tamaño de un lienzo proporcionado para su reutilización, independientemente de las dimensiones de la imagen de origen o de la región de origen. Tenga en cuenta que el lienzo y la región de origen deben tener la misma relación de aspecto para evitar que la imagen a escanear se distorsione, lo que podría imposibilitar la detección de códigos QR. De forma predeterminada, el tamaño del lienzo se adapta a las dimensiones de la región de escaneo o a una región de escaneo reducida para escanear una sola imagen. |
alsoTryWithoutScanRegion | Solicite un segundo escaneo de toda la imagen si se proporcionó una scanRegion y no se encontró ningún código QR dentro de esa región. De forma predeterminada, no se intenta ningún segundo análisis. |
returnDetailedScanResult | Haga cumplir la presentación de informes de resultados de análisis detallados, consulte a continuación. |
Para utilizar el valor predeterminado para una opción, omítalo o proporcione undefined
.
Los resultados devueltos dependen de si se proporcionó un objeto de opciones:
data
de propiedades que son el contenido de la cadena del código QR leído y cornerPoints
que son los puntos de las esquinas del contorno del código QR leído en la transmisión de la cámara. Para evitar el uso de la API obsoleta si no proporciona ninguna otra opción, puede proporcionar { returnDetailedScanResult: true }
para habilitar la nueva API y obtener el resultado del análisis detallado.
Si no se puede leer ningún código QR, se lanza scanImage
.
Esta biblioteca proporciona un método de utilidad para comprobar si el dispositivo tiene una cámara. Esto puede resultar útil para determinar si se debe ofrecer la función de escaneo de cámara web QR a un usuario.
QrScanner . hasCamera ( ) ; // async
Esta biblioteca proporciona un método de utilidad para obtener una lista de las cámaras del dispositivo, definidas mediante su id
y label
. Esto puede resultar útil para permitir que un usuario elija una cámara específica para usar.
Opcionalmente puedes solicitar las etiquetas de la cámara. Sin embargo, tenga en cuenta que esto requiere el permiso del usuario para acceder a las cámaras, que se le solicitará si aún no se lo ha concedido. Si no se solicitan específicamente, las etiquetas de dispositivo se determinan según el mejor esfuerzo, es decir, se devuelven etiquetas reales si ya se otorgaron permisos y etiquetas alternativas en caso contrario. Si desea solicitar etiquetas de cámaras, es recomendable llamar listCameras
después de que se haya iniciado exitosamente una instancia de QrScanner, ya que para entonces el usuario ya habrá dado su permiso.
QrScanner . listCameras ( ) ; // async; without requesting camera labels
QrScanner . listCameras ( true ) ; // async; requesting camera labels, potentially asking the user for permission
Puede cambiar la cámara preferida que se utilizará. La preferencia puede ser una identificación de dispositivo devuelta por listCameras
o un modo de orientación especificado como 'environment'
o 'user'
. Tenga en cuenta que no hay garantía de que la preferencia pueda cumplirse realmente.
qrScanner . setCamera ( facingModeOrDeviceId ) ; // async
El escáner busca de forma predeterminada códigos QR oscuros sobre un fondo brillante. Puedes cambiar este comportamiento para buscar códigos QR brillantes sobre un fondo oscuro o ambos al mismo tiempo:
qrScanner . setInversionMode ( inversionMode ) ;
Donde inversionMode
puede ser original
, invert
o both
. El valor predeterminado para el escaneo con cámara web es original
y para el escaneo de una sola imagen, both
.
Cambie los pesos de rojo, verde y azul en el cálculo de la escala de grises para mejorar el contraste de los códigos QR de un color específico:
qrScanner . setGrayscaleWeights ( red , green , blue , useIntegerApproximation = true ) ;
Donde red
, green
y blue
deberían sumar 256 si useIntegerApproximation === true
y 1
en caso contrario. De forma predeterminada, se utilizan estos valores.
En los navegadores compatibles, puede comprobar si la cámara utilizada actualmente tiene flash y encenderlo o apagarlo. Tenga en cuenta que se debe llamar a hasFlash después de que el escáner se haya iniciado exitosamente para evitar la necesidad de abrir una secuencia de cámara temporal solo para consultar si tiene soporte para flash, lo que podría solicitarle al usuario acceso a la cámara.
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.
Puedes destruir el escáner QR si ya no lo necesitas:
qrScanner . destroy ( ) ;
qrScanner = null ;
Esto detendrá la transmisión de la cámara y el trabajador web y limpiará los detectores de eventos. El escáner QR dejará de funcionar después de haber sido destruido.
El proyecto está precompilado en qr-scanner.min.js en combinación con qr-scanner-worker.min.js. Solo es necesario crearlo usted mismo si desea cambiar el código en la carpeta /src. Se requiere NodeJs para la construcción.
Instale los paquetes de compilación necesarios:
yarn
Edificio:
yarn build