QR Scanner Using JavaScript and jsQR Library: A Comprehensive Guide

QR (Quick Response) codes have become an integral part of our lives. From advertising to product packaging, QR codes are used to provide users with quick access to information. A QR scanner can be used to scan these codes, read the information encoded in them, and display it to the user.

In this tutorial, we will build a QR scanner using jsQR library in JavaScript. jsQR is a JavaScript library that provides an easy-to-use interface for decoding QR codes from image data. We will explore how to set up jsQR and how to use it to decode QR codes from the device camera feed.

Setting Up jsQR Library

First, we need to include the jsQR library in our HTML file. We can do this by adding the following script tag to the head section of our HTML file:

<script src="https://cdn.jsdelivr.net/npm/jsqr@2.0.5/dist/jsQR.min.js"></script>

This will load the latest version of jsQR from the jsDelivr CDN.

Using the Device Camera

Next, we need to access the device camera and capture video frames from it. We can do this using the getUserMedia method provided by the navigator.mediaDevices object. This method returns a Promise that resolves to a MediaStream object representing the video stream from the camera.

const constraints = { video: { facingMode: 'environment' } };
navigator.mediaDevices.getUserMedia(constraints)
    .then(function(stream) { 
        // code to display video stream in a video element 
    }) 
    .catch(function(error) { 
        console.error(error); 
    });

In the above code, we pass a constraints object to the getUserMedia method to specify the constraints for the video stream. In this case, we set facingMode to 'environment' to use the rear-facing camera. We then use the then method to handle the success case, and the catch method to handle errors.

Once we have access to the video stream, we can display it in a video element and capture frames from it.

const video = document.getElementById('video'); 
video.srcObject = stream; 
video.setAttribute('playsinline', true); 
video.play();

In the above code, we set the srcObject property of the video element to the MediaStream object we obtained from getUserMedia. We also set the playsinline attribute to true to allow the video to play inline on mobile devices. Finally, we call the play method to start playing the video.

Capturing Frames and Decoding QR Codes

To capture frames from the video stream, we need to create a canvas element and draw the video frames on it. We can then use the jsQR library to decode the QR codes from the canvas image data.

const canvas = document.createElement('canvas');
const outputDiv = document.getElementById('output');

function tick() {
  if (video.readyState === video.HAVE_ENOUGH_DATA) {
    canvas.width = video.videoWidth;
    canvas.height = video.videoHeight;
    const ctx = canvas.getContext('2d');
    ctx.drawImage(video, 0, 0, canvas.width, canvas.height);
    const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
    const code = jsQR(imageData.data, imageData.width, imageData.height);
        if (code) {
            outputDiv.innerHTML = code.data;
        }
    }
    requestAnimationFrame(tick);
}

In the above code, we create a canvas element and an output div element to display the decoded QR code data. We then define a `tick` function that will be called repeatedly to capture frames from the video stream and decode QR codes. Inside the `tick` function, we check if the video has enough data to play by checking the `readyState` property. If it does, we set the width and height of the canvas to the width and height of the video, and draw the current video frame on the canvas using the `drawImage` method of the `CanvasRenderingContext2D` interface. We then get the image data from the canvas using the `getImageData` method, and pass it to the `jsQR` function along with the width and height of the image. The `jsQR` function returns an object representing the decoded QR code if one is found, or `null` otherwise. If a QR code is found, we display its data in the output div element. Finally, we call the `requestAnimationFrame` method to schedule the next call to the `tick` function.

Here is the Full Code:

<!DOCTYPE html>
<html>
  <head>
    <title>QR Code Scanner</title>
    <script src="https://cdn.jsdelivr.net/npm/jsqr@1.4.0/dist/jsQR.min.js"></script>
  </head>
  <body>
    <video id="video" width="300" height="200"></video>
    <canvas id="canvas" style="display: none;"></canvas>
    <div id="output"></div>

    <script>
      const video = document.getElementById('video');
      const canvas = document.getElementById('canvas');
      const outputDiv = document.getElementById('output');
      const constraints = { video: { facingMode: 'environment' } };

      navigator.mediaDevices.getUserMedia(constraints)
        .then(function(stream) {
          video.srcObject = stream;
          video.setAttribute('playsinline', true);
          video.play();
          requestAnimationFrame(tick);
        })
        .catch(function(error) {
          console.error(error);
        });

      function tick() {
        if (video.readyState === video.HAVE_ENOUGH_DATA) {
          canvas.width = video.videoWidth;
          canvas.height = video.videoHeight;
          const ctx = canvas.getContext('2d');
          ctx.drawImage(video, 0, 0, canvas.width, canvas.height);
          const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
          const code = jsQR(imageData.data, imageData.width, imageData.height);
          if (code) {
            outputDiv.innerHTML = code.data;
          }
        }
        requestAnimationFrame(tick);
      }
    </script>
  </body>
</html>

Conclusion

In this tutorial, we learned how to build a QR scanner using `jsQR` library in JavaScript. We started by setting up the `jsQR` library and accessing the device camera to capture video frames. We then captured frames from the video stream and used `jsQR` to decode QR codes from them. By following the steps outlined in this tutorial, you can easily create a QR scanner using JavaScript and `jsQR` library. This can be useful for a variety of applications, including mobile apps, web apps, and more.

References

1. `jsQR` library documentation: https://github.com/cozmo/jsQR 2. `navigator.mediaDevices` documentation: https://developer.mozilla.org/en-US/docs/Web/API/Navigator/mediaDevices 3. `CanvasRenderingContext2D` interface documentation: https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D

No comments:

Post a Comment

If you have any doubts regarding the post. Please let me know.