Comment scanner les codes QR dans les navigateurs Web avec Web Workers et jsQR

0
81
shisu_ka/Shutterstock.com

codes QR sont devenus beaucoup plus populaires ces dernières années. Ils sont largement utilisés pour fournir des informations et faciliter les enregistrements. Bien que le plus souvent présent dans les applications mobiles natives, vous pouvez également incorporer des scans QR dans vos sites Web.

Voici comment utiliser la bibliothèque jsQR populaire en combinaison avec Web Workers pour offrir une expérience de numérisation QR haute performance sur le Web. Nous supposerons que vous connaissez déjà les bases de JavaScript et que vous disposez d'un site fonctionnel auquel vous êtes prêt à ajouter votre code.

1. Mise en route

Commencez par télécharger la bibliothèque jsQR au format distribuable précompilé. Assurez-vous qu'il est accessible au public sur votre serveur Web ; dans cet article, nous supposons que l'URL est /jsQR.js. jsQR est également disponible sous forme de package npm si vous avez configuré une routine de construction.

Ce package permet une détection en temps réel des codes QR visibles dans un flux vidéo. Il récupère les données dans le code et les fournit à votre application.

2. Obtenir un flux de caméra

L'étape suivante consiste à acquérir un MediaStream à partir du navigateur. Utilisez l'API mediaDevices pour obtenir un nouveau flux de la caméra de l'utilisateur :

const getCamera = async () => {   si (!navigator.mediaDevices) { lancer une nouvelle erreur("API mediaDevices non disponible."); }   const devices = wait navigator.mediaDevices.enumerateDevices(); const caméras = devices.filter(d => (d.kind === "videoinput")); caméras de retour[0];   }; Publicité

Nous sélectionnons la première caméra trouvée. Vous pouvez ajouter une logique supplémentaire pour permettre la sélection d'une caméra spécifique indiquée par l'utilisateur. Dans une vraie application, vous devez également améliorer la gestion des erreurs lorsque l'API mediaDevices n'est pas disponible. Cela peut être dû au fait que l'utilisateur utilise un ancien navigateur Web ou qu'il a définitivement bloqué l'autorisation d'accès à la caméra.

Utilisez la fonction getCamera() pour acquérir le flux vidéo. Attachez le flux à une <video> élément afin qu'il puisse être lu et affiché à l'utilisateur :

<vidéo autoplay="true" id="vidéo" muet="true" /> const stream = wait getCamera(); const video = document.getElementById("video");   video.srcObject = flux ; attendez video.play();

3. Création d'un canevas

L'étape suivante consiste à créer un élément canevas. Les données vidéo seront diffusées de la caméra sur le canevas où les pixels de l'image seront extraits et transmis à jsQR. Le canevas doit être dimensionné pour correspondre aux dimensions du flux vidéo.

const videoTracks = wait stream.getVideoTracks(); const videoTrackSettings = videoTracks[0].getSettings();   const canvas = document.createElement("canvas"); canvas.height = videoTrackSettings.height; canvas.width = videoTrackSettings.width;   const canvasContext = canvas.getContext("2d");

Le contexte du canevas sera utilisé à l'étape suivante pour dessiner chaque image du flux vidéo sur le canevas.

4. Ajout de jsQR

Ajoutez ensuite jsQR à votre code. L'exécution de jsQR dans un agent Web permet au navigateur de le déléguer à un processus d'arrière-plan, améliorant ainsi les performances. jsQR doit analyser chaque image vidéo, donc son exécution dans votre fil JavaScript principal peut entraîner de graves ralentissements sur les appareils bas de gamme.

Le fil principal et votre travailleur Web peuvent communiquer à l'aide de messages. Votre fil principal enverra un message au travailleur jsQR chaque fois qu'une nouvelle image vidéo est disponible. Le travailleur inspectera ce cadre pour les codes QR dans son fil d'arrière-plan, puis enverra un message au fil principal lorsque le cadre aura été traité.

Publicité

Chargez votre travailleur dans votre code JavaScript principal et ajoutez un écouteur de messages :

const qrWorker = new Worker("/qr-worker.js");   qrWorker.addEventListener("message", ({données}) => {   si (données) { //Données du code QR disponibles ////Gérez un scan réussi ici. } sinon { //Aucun code QR détecté dans ce cadre ////Envoyez le prochain cadre au travailleur QR //maintenant (ce code est présenté ci-dessous). cochez(); }   });

Ajoutez ensuite qr-worker.js à votre projet. Cela doit être accessible au public à l'URL donnée au constructeur Worker. Les navigateurs téléchargeront l'outil de travail Web au moment où cela sera nécessaire.

importScripts("jsQR.js");   self.addEventListener("message", e => { const {données, largeur, hauteur} = e.données; const qrData = jsQR(données, largeur, hauteur); self.postMessage(qrData); });

La fonction importScripts() télécharge la bibliothèque jsQR. Cet appel équivaut à un <script> dans votre code HTML, mais rend le contenu du script disponible pour votre agent Web.

Un écouteur de message est ajouté pour recevoir les événements du fil principal de votre JavaScript. Chaque événement doit inclure les données, la largeur et la hauteur d'une image vidéo diffusée depuis la caméra. Ces valeurs sont transmises à jsQR qui tentera de détecter un code QR dans le cadre. Le résultat est posté sur le fil principal.

5. Tout câbler

La dernière étape consiste à créer une boucle de mise à jour qui transmet périodiquement des images vidéo au travailleur jsQR.

const updateJsQr = () => { canvasContext.drawImage(vidéo, 0, 0, canvas.width, canvas.height); const imageData = canvasContext.getImageData0, 0, canvas.width, canvas.height); qrWorker.postMessage({data: imageData, hauteur: canvas.height, largeur: canvas.width}); }   coche const = () => requestAnimationFrame(updateJsQr);   cochez();

La fonction tick() demande au navigateur d'allouer du temps à l'appel de updateJsQr() avant le prochain repaint. Cette fonction obtient l'image vidéo actuelle, la dessine sur le canevas, puis extrait les données d'image résultantes prêtes à être transmises à jsQR. La méthode postMessage() sur l'instance de travail envoie réellement les données.

Publicité

Le travailleur agira alors sur les données comme indiqué dans le code ci-dessus. Le résultat de la détection est communiqué au thread principal qui le traite comme indiqué à l'étape 4. Lorsqu'un code QR est détecté, votre application doit utiliser les données récupérées pour avancer dans son flux. Lorsqu'aucun code n'est détecté, tick() est à nouveau appelé pour transmettre la trame suivante au travailleur QR, prêt pour l'évaluation.

Ce mécanisme garantit que vous ne finirez pas par surcharger le navigateur en exécutant plusieurs détections de trames simultanément. Chaque appel à jsQR() est potentiellement coûteux, vous devez donc attendre que le résultat soit connu avant d'en programmer un autre. La boucle n'est maintenue que jusqu'à ce qu'un résultat réussi soit obtenu, jsQR gérant une image à la fois. L'interface utilisateur de votre site et l'aperçu de sa caméra en temps réel resteront réactifs tout au long du processus, car le travailleur s'exécute indépendamment en arrière-plan.

6. jsQR Result Data

Chaque appel réussi à jsQR() renvoie un objet de résultat avec les propriétés suivantes :

  • data – Données de chaîne extraites du code QR (c'est la seule propriété utilisée dans l'exemple ci-dessus).
  • Données binaires – Un Uint8ClampedArray contenant les octets bruts lus à partir du code QR.
  • version – Version du code QR détectée.
  • emplacement – Un objet qui décrit la position du code QR détecté dans l'image vidéo, y compris les points pour chaque coin.

Aucune donnée n'est disponible lorsque jsQR ne parvient pas à détecter un code dans l'image fournie.< /p>

7. Conclusion

La combinaison de jsQR avec Web Workers vous permet de mettre en œuvre des analyses de code QR hautes performances dans votre application Web. Les codes QR sont un mécanisme de partage de données simple et pratique que la plupart des utilisateurs mobiles connaissent maintenant.

Bien que vous puissiez utiliser jsQR dans le cadre de votre boucle principale, vous devez mettre en œuvre une limitation agressive pour maintenir votre interface utilisateur réactive. Cela entraînerait un délai plus long avant une détection réussie. Les Web Workers sont pris en charge dans tous les navigateurs modernes et améliorent considérablement les performances de cette solution, permettant des analyses en une fraction de seconde dans des conditions d'éclairage optimales.