Creating a QR Code Scanner With Vanilla JavaScript - Fletcher Rippon
By: Fletcher Rippon
Tags: Qr Code, Programming, Website Development, JavaScript, Vanilla Javascript

Let's Start Coding!

Creating the basic HTML layout

The first thing we are going to do is very easy, creating the basic HTML all we are going to add for this example is a <video> tag with an id and some other attributes, you can add more elements to make the layout more interesting we will be doing that in part 2 of this article.

We are going to use the id to select the element with our JavaScript code later on. The width and height can be set to whatever you like for this example I'm setting them to 640px by 480px . The autoplay attribute is needed to play our stream nothing will happen without autoplay .

Creating the video stream

Now it's time to start writing some JavaScript, firstly we are going to select the video element from the page we just created then check if there is a camera available that we can stream from if there is then start streaming to the video element.

Now if you open the browser you should see a live stream from your webcam that we can use to scan barcodes and QR codes.

Creating the barcode scanner functionality

First, we need to create a new BarcodeDetector class and declare the barcodes that we want our barcode scanner to detect for this example I only want to scan QR codes so that's the only one I will add.

Creating the bar code detector (to add more codes add the code name to the formats array)

You can go to the MDN docs or scroll to the top of the page to see what codes are supported if you would like to scan more than QR codes. If you want to use all supported formats you can use the getSupportedFormats function.

Get supported formats is an async function so you need to use then() or an await to resolve the promise

Now that we have the barcodeDetactor class, we can start making the barcode detector function.

To start detecting barcodes we use the BarcodeDetector.detect() this method takes a parameter this can be a element , blob (type of image) or an ImageData object. Once the BarcodeDetector has detected a code we first check to see if the array is empty if it is we will leave the function then we log each code to the console. But before we can see our barcodes data getting returned to the console we need to run this function over and over again to get it in real-time we can do this really easily by using the setInterval method.

Now you can start scanning barcodes and see that data is getting returned to the console. The data should look something like this.

In this object, there are four properties boundingBox , cornerPoints , format and rawValue . The format and rawValue properties are easy to understand the formate is the formate of the code that was read in this case it was a QR code and the rawValue is the value/content of the barcode.

We also have the boundingBox and cornerPoints these both hold data on the shape and position of the barcode this data may look like they achieve the same thing but they do have differences and can change the shape they draw depending on the code you are scanning and how that code gets scanned.

Corner points

The cornerPoints array holds all four points of the scan area starting from the top left corner and continuing clockwise so cornerPoints[0] is equal to the top left then cornerPoints[1] is equal to the top right and so on. If we draw a line from each point it is unlikely that it will be a perfect square or rectangle due to the perspective of the code that the camera is looking from.

It is important to truly understand what the scan area is and what the result could be depending on the code you use for example QR, aztec, data matrix codes and other codes similar to them, this will outline the whole code because the scanner needs to be scan to the entire area to retrieve the raw value of the code.

While codes like ean 8/13, code 39/93/128, Codabar, and more like these don't need to scan the entire area of the code they just have to scan across the entire width and a small amount of the height of these codes. Here is an illustration to make this a bit easier to understand.

This image represents how different codes are scanned and how the results from the cornerPoints data can look for different barcodes

Bounding box