Scanner de code QR Javascript basé sur le port javascript de Cosmo Wolfe de la bibliothèque ZXing de Google.
Dans cette bibliothèque, plusieurs améliorations ont été appliquées par rapport au port d'origine :
BarcodeDetector
natif est disponible, seuls ~15,3 Ko (~5,6 Ko gzippés) sont chargés.Selon notre analyse comparative, le taux de détection du moteur de scanner de ce projet est environ 2 à 3 fois (et jusqu'à 8 fois) plus élevé que celui de la bibliothèque de scanner QR javascript la plus populaire, LazarSoft/jsqrcode. De plus, l'autre bibliothèque interprète souvent mal le contenu des codes QR, alors que pour ce projet, aucune erreur de lecture ne s'est produite lors de l'analyse comparative.
La bibliothèque prend en charge la numérisation d'un flux vidéo continu à partir d'une webcam ainsi que la numérisation d'images uniques.
Le développement de cette bibliothèque est sponsorisé par nimiq, la première blockchain au monde basée sur un navigateur.
Voir https://nimiq.github.io/qr-scanner/demo/
Pour installer via npm :
npm install --save qr-scanner
Pour installer via du fil :
yarn add qr-scanner
Ou copiez simplement qr-scanner.min.js
et qr-scanner-worker.min.js
dans votre projet.
Le QR Scanner se compose de deux fichiers principaux. qr-scanner.min.js
est le fichier API principal qui charge le script de travail qr-scanner-worker.min.js
via une importation dynamique, uniquement si nécessaire. Si vous n'utilisez pas un bundle tel que Rollup ou Webpack qui gère automatiquement les importations dynamiques, vous devrez peut-être copier qr-scanner-worker.min.js
dans votre distribution, à côté de qr-scanner.min.js
ou à côté du script. dans lequel vous regroupez qr-scanner.min.js
.
qr-scanner.min.js
est un module es6 et peut être importé comme suit :
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
Cela nécessite que le script d'importation soit également un module es6 ou une balise de script de module, par exemple :
< script type =" module " >
import QrScanner from 'path/to/qr-scanner.min.js' ;
// do something with QrScanner
</ script >
Si votre projet n'est pas basé sur des modules es6 vous pouvez
import ( 'path/to/qr-scanner.min.js' ) . then ( ( module ) => {
const QrScanner = module . default ;
// do something with QrScanner
} ) ;
qr-scanner.umd.min.js
pour une utilisation directe en tant que script non-module < script src =" path/to/qr-scanner.umd.min.js " > </ script >
< script >
// do something with QrScanner
</ script >
qr-scanner.umd.min.js
directement avec votre code non-module avec des outils comme gulp ou grunt.require
comme 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
Cette bibliothèque utilise les fonctionnalités ECMAScript 2017 telles que les fonctions async
. Si vous devez prendre en charge d'anciens navigateurs, vous pouvez utiliser qr-scanner.legacy.min.js
, qui est compatible ECMAScript 2015 (ES6). Il s'agit d'une version UMD et peut être utilisée en remplacement de qr-scanner.umd.min.js
, voir ci-dessus. Notez que la version héritée est plus grande car elle inclut certains polyfills et, pour prendre en charge les navigateurs qui ne prennent pas en charge les importations dynamiques, intègre le script de travail qui devrait cependant de toute façon être chargé dans les navigateurs existants. Cependant, vous n'aurez probablement pas besoin d'utiliser la version existante, car la prise en charge générale du navigateur est déjà très bonne pour la version standard. Surtout si vous souhaitez numériser à partir de l'appareil photo de l'appareil, la prise en charge de l'appareil photo par le navigateur constitue la restriction la plus stricte.
Créez un élément <video>
où le flux vidéo de la webcam doit être rendu :
< 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.
) ;
En tant que troisième paramètre facultatif, un objet options peut être fourni. Les options prises en charge sont :
Option | Description |
---|---|
onDecodeError | Gestionnaire à appeler en cas d’erreurs de décodage. La valeur par défaut est QrScanner._onDecodeError . |
preferredCamera | Préférence pour la caméra à utiliser. La préférence peut être soit un identifiant de périphérique tel que renvoyé par listCameras , soit un mode d'orientation spécifié comme 'environment' ou 'user' . La valeur par défaut est 'environment' . Notez qu’il n’y a aucune garantie que la préférence puisse réellement être satisfaite. |
maxScansPerSecond | Cette option peut être utilisée pour limiter les analyses afin de réduire la consommation de la batterie. La valeur par défaut est 25. Si le navigateur le prend en charge, la fréquence de numérisation n'est jamais supérieure à la fréquence d'images de la caméra afin d'éviter des numérisations en double inutiles sur la même image. |
calculateScanRegion | Méthode qui détermine une région à laquelle l’analyse doit être limitée pour améliorer les performances. Cette région peut éventuellement également être réduite avant d'effectuer l'analyse afin d'améliorer davantage les performances. La région est spécifiée comme x , y , width et height ; les dimensions de la région réduite comme downScaledWidth et downScaledHeight . Notez que le rapport hauteur/largeur entre width et height et downScaledWidth et downScaledHeight doivent rester les mêmes. Par défaut, la zone d'analyse est limitée à un carré centré des deux tiers de la largeur ou de la hauteur de la vidéo, selon la valeur la plus petite, et réduite à un carré de 400 x 400. |
highlightScanRegion | Définissez cette option sur true pour afficher un contour autour de la région de numérisation sur le flux vidéo. Cela utilise un div positionné de manière absolue qui couvre la région d'analyse. Ce div peut être soit fourni en option overlay , voir ci-dessous, soit créé automatiquement puis accessible via qrScanner.$overlay . Il peut être librement stylisé via CSS, par exemple en définissant un contour, une bordure, une couleur d'arrière-plan, etc. Voir la démo pour des exemples. |
highlightCodeOutline | Définissez cette option sur true pour afficher un contour autour des codes QR détectés. Cela utilise un div positionné de manière absolue sur lequel un SVG pour le rendu du contour sera placé. Ce div peut soit être fourni en option overlay , voir ci-dessous, soit être accessible via qrScanner.$overlay . Le SVG peut être librement stylisé via CSS, par exemple en définissant la couleur de remplissage, la couleur du trait, la largeur du trait, etc. Voir la démo pour des exemples. Pour des besoins plus particuliers, vous pouvez également utiliser directement les cornerPoints , voir ci-dessous, pour restituer vous-même un contour ou les points. |
overlay | Un div personnalisé qui peut être fourni pour être utilisé pour highlightScanRegion et highlightCodeOutline . Le div doit être un frère de videoElem dans le DOM. Si cette option est fournie, les styles par défaut pour highlightCodeOutline ne sont pas appliqués car on s'attend à ce que l'élément ait déjà un style personnalisé qui lui est appliqué. |
returnDetailedScanResult | Appliquez la création de rapports sur les résultats d’analyse détaillés, voir ci-dessous. |
Pour utiliser la valeur par défaut d'une option, omettez-la ou fournissez undefined
.
Les résultats transmis au rappel dépendent du fait qu'un objet d'options a été fourni :
data
de propriétés qui sont le contenu de la chaîne du code QR lu et cornerPoints
qui sont les points d'angle du contour du code QR lu sur le flux de la caméra. Pour éviter l'utilisation de l'API obsolète si vous ne fournissez aucune autre option, vous pouvez fournir { returnDetailedScanResult: true }
pour activer la nouvelle API et obtenir le résultat détaillé de l'analyse.
qrScanner . start ( ) ;
Appelez-le lorsque vous êtes prêt à numériser, par exemple en cliquant sur un bouton ou directement au chargement de la page. Il demandera à l'utilisateur l'autorisation d'utiliser une caméra. Remarque : pour lire à partir d'un flux Web Cam, votre page doit être servie via HTTPS.
qrScanner . stop ( ) ;
Si vous le souhaitez, vous pouvez arrêter l'analyse à tout moment et la reprendre en appelant à nouveau start()
.
QrScanner . scanImage ( image )
. then ( result => console . log ( result ) )
. catch ( error => console . log ( error || 'No QR code found.' ) ) ;
Les sources d'images prises en charge sont : HTMLImageElement, SVGImageElement, HTMLVideoElement, HTMLCanvasElement, ImageBitmap, OffscreenCanvas, File/Blob, URI de données, URL pointant vers une image (si elles se trouvent sur la même origine ou si CORS est activé)
En tant que deuxième paramètre facultatif, un objet options peut être fourni. Les options prises en charge sont :
Option | Description |
---|---|
scanRegion | Une région définie par x , y , width et height à laquelle la recherche d'un code QR doit être limitée. Pour améliorer les performances, cette région peut être réduite avant d'effectuer l'analyse en fournissant un downScaledWidth et downScaledHeight . Notez que le rapport hauteur/largeur entre width et height et downScaledWidth et downScaledHeight doivent rester les mêmes. Par défaut, la région s'étend sur toute l'image et n'est pas réduite. |
qrEngine | Une instance du moteur de scanner QR créée manuellement à réutiliser. Cela améliore les performances si vous numérisez beaucoup d'images. Un moteur peut être créé manuellement via QrScanner.createQrEngine(QrScanner.WORKER_PATH) . Par défaut, aucun moteur n'est réutilisé pour la numérisation d'une seule image. |
canvas | Un canevas créé manuellement à réutiliser. Cela améliore les performances si vous numérisez beaucoup d'images. Un canevas peut être créé manuellement via une balise <canvas> dans votre balisage ou document.createElement('canvas') . Par défaut, aucune toile n'est réutilisée pour la numérisation d'une seule image. |
disallowCanvasResizing | Demandez qu'un canevas fourni soit réutilisé et ne soit pas redimensionné, quelles que soient les dimensions de l'image source ou de la région source. Notez que le canevas et la région source doivent avoir le même rapport hauteur/largeur pour éviter que l'image à numériser ne soit déformée, ce qui pourrait rendre impossible la détection des codes QR. Par défaut, la taille du canevas est adaptée aux dimensions de la région de numérisation ou à la région de numérisation réduite pour la numérisation d'une seule image. |
alsoTryWithoutScanRegion | Demandez une deuxième analyse de l'image entière si une scanRegion a été fournie et qu'aucun code QR n'a été trouvé dans cette région. Par défaut, aucune deuxième analyse n'est tentée. |
returnDetailedScanResult | Appliquez la création de rapports sur les résultats d’analyse détaillés, voir ci-dessous. |
Pour utiliser la valeur par défaut d'une option, omettez-la ou fournissez undefined
.
Les résultats renvoyés dépendent du fait qu'un objet d'options a été fourni :
data
de propriétés qui sont le contenu de la chaîne du code QR lu et cornerPoints
qui sont les points d'angle du contour du code QR lu sur le flux de la caméra. Pour éviter l'utilisation de l'API obsolète si vous ne fournissez aucune autre option, vous pouvez fournir { returnDetailedScanResult: true }
pour activer la nouvelle API et obtenir le résultat détaillé de l'analyse.
Si aucun code QR n'a pu être lu, scanImage
est lancé.
Cette bibliothèque fournit une méthode utilitaire pour vérifier si l'appareil dispose d'une caméra. Cela peut être utile pour déterminer s'il convient d'offrir la fonctionnalité de numérisation par webcam QR à un utilisateur.
QrScanner . hasCamera ( ) ; // async
Cette bibliothèque fournit une méthode utilitaire pour obtenir une liste des caméras de l'appareil, définies via leur id
et label
. Cela peut être utile pour permettre à un utilisateur de choisir une caméra spécifique à utiliser.
Vous pouvez éventuellement demander les étiquettes de la caméra. Notez que cela nécessite cependant l'autorisation de l'utilisateur pour accéder aux caméras, qui lui sera demandée si elle n'est pas déjà accordée. Si cela n'est pas spécifiquement demandé, les étiquettes des appareils sont déterminées au mieux, c'est-à-dire que les étiquettes réelles sont renvoyées si les autorisations ont déjà été accordées et les étiquettes de secours dans le cas contraire. Si vous souhaitez demander des étiquettes de caméra, il est recommandé d'appeler listCameras
après le démarrage réussi d'une instance de QrScanner, car l'utilisateur aura alors déjà donné son autorisation.
QrScanner . listCameras ( ) ; // async; without requesting camera labels
QrScanner . listCameras ( true ) ; // async; requesting camera labels, potentially asking the user for permission
Vous pouvez modifier la caméra préférée à utiliser. La préférence peut être soit un identifiant de périphérique tel que renvoyé par listCameras
, soit un mode d'orientation spécifié comme 'environment'
ou 'user'
. Notez qu’il n’y a aucune garantie que la préférence puisse réellement être satisfaite.
qrScanner . setCamera ( facingModeOrDeviceId ) ; // async
Le scanner recherche par défaut les codes QR sombres sur un fond clair. Vous pouvez modifier ce comportement pour rechercher des codes QR clairs sur fond sombre ou les deux en même temps :
qrScanner . setInversionMode ( inversionMode ) ;
Où inversionMode
peut être original
, invert
ou both
. La valeur par défaut pour la numérisation par webcam est original
et pour la numérisation d'une seule image, both
.
Modifiez les poids du rouge, du vert et du bleu dans le calcul des niveaux de gris pour améliorer le contraste des codes QR d'une couleur spécifique :
qrScanner . setGrayscaleWeights ( red , green , blue , useIntegerApproximation = true ) ;
Où red
, green
et blue
devraient totaliser 256 si useIntegerApproximation === true
et 1
sinon. Par défaut, ces valeurs sont utilisées.
Sur les navigateurs pris en charge, vous pouvez vérifier si l'appareil photo actuellement utilisé dispose d'un flash et l'allumer ou l'éteindre. Notez que hasFlash doit être appelé après le démarrage réussi du scanner pour éviter d'avoir à ouvrir un flux de caméra temporaire simplement pour demander s'il prend en charge le flash, demandant potentiellement à l'utilisateur d'accéder à la caméra.
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.
Vous pouvez détruire le scanner QR si vous n'en avez plus besoin :
qrScanner . destroy ( ) ;
qrScanner = null ;
Cela arrêtera le flux de la caméra et le Web Worker et nettoiera les écouteurs d'événements. Le scanner QR sera dysfonctionnel après sa destruction.
Le projet est pré-construit dans qr-scanner.min.js en combinaison avec qr-scanner-worker.min.js. La construction vous-même n'est nécessaire que si vous souhaitez modifier le code dans le dossier /src. NodeJs est requis pour la construction.
Installez les packages de build requis :
yarn
Bâtiment:
yarn build