So scannen Sie QR-Codes in Webbrowsern mit Webworkern und jsQR

0
54
shisu_ka/Shutterstock.com

QR-Codes sind in den letzten Jahren immer beliebter geworden. Sie werden häufig verwendet, um Informationen bereitzustellen und das Einchecken zu erleichtern. Obwohl sie am häufigsten als Teil nativer mobiler Apps zu finden sind, können Sie auch QR-Scans in Ihre Websites integrieren.

So verwenden Sie die beliebte jsQR-Bibliothek in Kombination mit Web Workern, um ein leistungsstarkes QR-Scan-Erlebnis im Web zu bieten. Wir gehen davon aus, dass Sie bereits mit den JavaScript-Grundlagen vertraut sind und eine funktionierende Website haben, zu der Sie Ihren Code hinzufügen können.

1. Erste Schritte

Beginnen Sie mit dem Herunterladen der jsQR-Bibliothek im vorkompilierten verteilbaren Format. Stellen Sie sicher, dass es auf Ihrem Webserver öffentlich zugänglich ist. In diesem Artikel gehen wir davon aus, dass die URL /jsQR.js ist. jsQR ist auch als npm-Paket verfügbar, wenn Sie eine Build-Routine konfiguriert haben.

Dieses Paket bietet die Echtzeiterkennung von QR-Codes, die in einem Videostream sichtbar sind. Es ruft die Daten innerhalb des Codes ab und liefert sie an Ihre Anwendung.

2. Abrufen eines Kamera-Feeds

Der nächste Schritt besteht darin, einen MediaStream vom Browser abzurufen. Verwenden Sie die mediaDevices API, um einen neuen Stream von der Kamera des Nutzers abzurufen:

const getCamera = async () => {   wenn (!navigator.mediaDevices) { Throw new Error("mediaDevices API nicht verfügbar."); }   const devices = wait navigator.mediaDevices.enumerateDevices(); const camera = devices.filter(d => (d.kind === "Videoeingang")); Rückfahrkameras[0];   }; Werbung

Wir wählen die erste gefundene Kamera aus. Sie können zusätzliche Logik hinzufügen, um die Auswahl einer bestimmten vom Benutzer angegebenen Kamera zu ermöglichen. In einer echten App sollten Sie auch die Fehlerbehandlung verbessern, wenn die mediaDevices API nicht verfügbar ist. Dies kann daran liegen, dass der Benutzer einen alten Webbrowser verwendet oder die Zugriffsberechtigung für die Kamera dauerhaft blockiert hat.

Verwenden Sie die Funktion getCamera(), um den Videostream zu erfassen. Hängen Sie den Stream an ein <Video> Element, damit es abgespielt und dem Benutzer angezeigt werden kann:

<Video-Autoplay="true" id="Video" muted="true" /> const stream = erwarten getCamera(); const video = document.getElementById("video");   video.srcObject = stream; warten video.play();

3. Erstellen eines Canvas

Der nächste Schritt besteht darin, ein Canvas-Element zu erstellen. Die Videodaten werden von der Kamera auf die Leinwand gestreamt, wo die Bildpixel extrahiert und jsQR zugeführt werden. Die Größe der Leinwand muss den Abmessungen des Videostreams entsprechen.

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");

Der Canvas-Kontext wird im nächsten Schritt verwendet, um jeden Frame des Videostreams auf den Canvas zu zeichnen.

4. jsQR hinzufügen

Fügen Sie als nächstes jsQR zu Ihrem Code hinzu. Durch Ausführen von jsQR in einem Web-Worker kann der Browser es an einen Hintergrundprozess delegieren, wodurch die Leistung verbessert wird. jsQR muss jeden Videoframe scannen, damit die Ausführung in Ihrem JavaScript-Hauptthread auf Low-End-Geräten zu erheblichen Verlangsamungen führen kann.

Der Hauptthread und Ihr Webworker können über Nachrichten kommunizieren. Ihr Hauptthread benachrichtigt den jsQR-Worker jedes Mal, wenn ein neuer Videoframe verfügbar ist. Der Worker überprüft diesen Frame in seinem Hintergrundthread auf QR-Codes und sendet dann eine Nachricht an den Hauptthread, wenn der Frame verarbeitet wurde.

Werbung

Laden Sie Ihren Worker in Ihren Haupt-JavaScript-Code und fügen Sie hinzu ein Nachrichten-Hörer:

const qrWorker = neuer Worker("/qr-worker.js");   qrWorker.addEventListener("message", ({data}) => {   wenn (Daten) { //Daten vom QR-Code verfügbar ////Behandeln Sie hier einen erfolgreichen Scan. } sonst { //Kein QR-Code in diesem Frame erkannt ////Jetzt den nächsten Frame an den QR-Worker füttern (dieser Code wird unten eingeführt). Häkchen(); }   });

Als nächstes fügen Sie Ihrem Projekt qr-worker.js hinzu. Dies muss unter der URL, die dem Worker-Konstruktor übergeben wurde, öffentlich zugänglich sein. Browser laden den Web Worker zum gewünschten Zeitpunkt herunter.

importScripts("jsQR.js");   self.addEventListener("message", e => { const {Daten, Breite, Höhe} = e.Daten; const qrData = jsQR(Daten, Breite, Höhe); self.postMessage(qrData); });

Die Funktion importScripts() lädt die jsQR-Bibliothek herunter. Dieser Aufruf entspricht einem <script> -Tag in Ihrem HTML-Code, stellt jedoch den Inhalt des Skripts Ihrem Webworker zur Verfügung.

Ein Nachrichten-Listener wird hinzugefügt, um Ereignisse aus Ihrem JavaScript-Hauptthread zu empfangen. Jedes Ereignis muss die Daten, Breite und Höhe eines von der Kamera gestreamten Videoframes enthalten. Diese Werte werden an jsQR übergeben, das versucht, einen QR-Code innerhalb des Frames zu erkennen. Das Ergebnis wird zurück in den Hauptthread gepostet.

5. Alles verkabeln

Der letzte Schritt besteht darin, eine Aktualisierungsschleife zu erstellen, die dem jsQR-Worker regelmäßig Videoframes zuführt.

const updateJsQr = () => { canvasContext.drawImage(video, 0, 0, canvas.width, canvas.height); const imageData = canvasContext.getImageData(0, 0, canvas.width, canvas.height); qrWorker.postMessage({data: imageData, height: canvas.height, width: canvas.width}); }   konstantes Häkchen = () => requestAnimationFrame(updateJsQr);   Häkchen();

Die Funktion tick() fordert den Browser auf, dem Aufruf von updateJsQr() vor dem nächsten Repaint Zeit zuzuweisen. Diese Funktion ruft den aktuellen Videoframe ab, zeichnet ihn auf die Leinwand und holt dann die resultierenden Bilddaten heraus, die an jsQR übergeben werden können. Die Methode postMessage() auf der Worker-Instanz sendet die Daten tatsächlich.

Werbung

Der Worker wird dann auf die Daten reagieren, wie im obigen Code gezeigt. Das Erkennungsergebnis wird an den Haupt-Thread zurückgesendet, der es wie in Schritt 4 gezeigt verarbeitet. Wenn ein QR-Code erkannt wird, sollte Ihre Anwendung die abgerufenen Daten verwenden, um im Fluss voranzukommen. Wenn kein Code erkannt wird, wird tick() erneut aufgerufen, um den nächsten Frame an den QR-Worker zu übergeben, der zur Bewertung bereit ist.

Dieser Mechanismus stellt sicher, dass Sie den Browser nicht durch die gleichzeitige Ausführung mehrerer Frame-Erkennungen überlasten. Jeder Aufruf von jsQR() ist potenziell teuer, daher sollten Sie warten, bis das Ergebnis bekannt ist, bevor Sie einen weiteren planen. Die Schleife wird nur aufrechterhalten, bis ein erfolgreiches Ergebnis erzielt wird, wobei jsQR jeweils einen Frame verarbeitet. Die Benutzeroberfläche Ihrer Website und die Echtzeit-Kameravorschau bleiben während der gesamten Zeit reaktionsfähig, da der Worker unabhängig im Hintergrund ausgeführt wird.

6. jsQR-Ergebnisdaten

Jeder erfolgreiche Aufruf von jsQR() gibt ein Ergebnisobjekt mit den folgenden Eigenschaften zurück:

  • data – String-Daten, die aus dem QR-Code extrahiert wurden (dies ist die einzige Eigenschaft, die im obigen Beispiel verwendet wird).
  • binäreDaten – Ein Uint8ClampedArray, das die Rohbytes enthält, die aus dem QR-Code gelesen wurden.
  • Version – QR-Code-Version erkannt.
  • Standort – Ein Objekt, das die Position des erkannten QR-Codes innerhalb des Videoframes beschreibt, einschließlich der Punkte für jede Ecke.

Keine Daten verfügbar, wenn jsQR keinen Code im bereitgestellten Bild erkennt.< /p>

7. Fazit

Durch die Kombination von jsQR mit Web Workern können Sie leistungsstarke QR-Code-Scans in Ihrer Webanwendung implementieren. QR-Codes sind ein einfacher und bequemer Mechanismus zum Teilen von Daten, mit dem die meisten mobilen Benutzer inzwischen vertraut sind.

Obwohl Sie jsQR als Teil Ihrer Hauptschleife verwenden könnten, müssen Sie aggressive Drosselung implementieren, um dies zu gewährleisten Ihre Benutzeroberfläche reagiert. Dies würde zu einer längeren Verzögerung bis zu einer erfolgreichen Erkennung führen. Web Worker werden in allen modernen Browsern unterstützt und verleihen dieser Lösung einen erheblichen Leistungsschub, da sie Sekundenbruchteile unter optimalen Lichtverhältnissen scannen können.