QR Code scanner using HTML5 and Javascript
LazarSoft had written an excellent set of QR code decoding javascript libraries. However, it still requires some efforts to integrate the work with a web project as we need to take care of enumerating different camera devices, setting up canvas
or the video
element and hooking the stream with qrcode library
. Also recently, in leu of privacy concerns, some javascript APIs related to accessing the camera has changed and it requires some efforts to ensure different platforms like mobile or PC, chrome or safari support it. To reduce these pain points I wrote a jQuery based wrapper on to abstract tasks like camera enumeration and UI setup - it can be found at mebjas/html5-qrcode. In this article I have documented some details on how to use it and what is happening under the hook.
Deprecation Notice
This article is now obsolete as v1.0.0
introduced multiple refactors. Checkout this article on how to use this library now.
Introduction
QR Code is a very common technique of encoding information as images. Its a very common used in physical stores for identifying products like bar code is used.
Figure: A sample QR code
The jQuery
library available at mebjas/html5-qrcode on Github allows users to add a QR code scanner in their web applications. It works cross-platform and across different devices like PC, Mac or smartphones. It uses the stream
from the camera and try to decode frames at certain frequency (configurable) and notify the caller about results via callbacks. Requesting camera usually results in a popup to user for permissions and can only be used if the user grants the permission.
Figure: Sample permission flow triggered by Chrome browser on Mac
Demonstration
A demo for this project is hosted at https://blog.minhazav.dev/research/html5-qrcode.html
How to use
Clone the project and include the libraries
Clone the project at an appropriate location in your project.
git clone https://github.com/mebjas/html5-qrcode.git
Include the three main libraries into your HTML page
<script src="./jqeury.js"></script>
<script src="./jsqrcode-combined.js"></script>
<script src="./html5-qrcode.js"></script>
Add a palceholder element in HTML
<div id="reader"></div>
Add an empty HTML element at an appropriate position in your HTML code, give it an id
. The library uses this element to insert some hidden HTML elements which shows up as a viewfinder (camera input is shown in this HTML element) to the user performing QR code scan.
Enumerate all available cameras
The library exposes a method just for this called html5_qrcode_getSupportedCameras(..)
. It takes two callbacks as arguments namely successCallback
and errorCallback
.
This method takes in two callbacks. One for success and later one for failures. Both callbacks have this kind of interface:
interface Device {
id: String; // Id of the camera
label: String; // User visible name of the camera like
// Front Camera. This is not always set
// for all devices from privacy standpoint.
}
successCallback: Function(Array(Device))
errorCallback: Function(String)
Sample code:
Once you have cameraId
you can perform start/stop operations
Starting the camera implicitly starts QR Code scanning. It runs at a certain fps provided in ExtraConfiguration
. This is an optional field and by default the scanner runs at 2 fps
.
Use html5_qrcode()
to start scanning. Once you call this with sucess, it’d start streaming the camera input to a video
and canvas
element. Also, QR code library would be processing the frames at a certain frequency configurable by users. The method looks like:
interface ExtraConfiguration {
fps: Integer; // frames per seconds to be processed.
}
html5_qrcode(
cameraId: String,
qrcodeSuccessCallback: Function(qrCodeMessage: String),
qrcodeErrorCallback: Function(errorMessage: String),
videoErrorCallback: Function(errorMessage: String),
config: ExtraConfiguration
) : Function
Except config
other arguments are important and should be sent as argument.
The difference between qrcodeErrorCallback
and videoErrorCallback
is that the former one is called in case of QR code processing failure while latter is called during the setup part or in case of issues related to initialization or access.
Sample code:
For stopping an ongoing scanning, just call
This disables and hides the viewfinder shown during scanning and cleans up the resources. html5_qrcode(..)
can be called again after this method.
Sample implementation
Link to source code for the demo project - research/html5qrcode at blog.minhazav.dev
How to contribute
If you are excited or interested you can contribute to this project by:
- Raising issues for bugs faced, at Github issue page for the project. Feel free to add some related interesting discussions which could be taken up as work-item.
- Sending a Pull Request for bugs fixed by you.
- Rating the project with stars and shares.
- Sponsor the project with Github Sponsorship
Screenshots
Figure: Demo running on Chrome browser on Macbook Pro
Figure: Demo running on Safari browser on iPad
Figure: Demo running on Chrome browser on Pixel 3 (Android)
References
- QR Code on Wikipedia - Wikipedia
- Project on Github - mebjas/html5-qrcode
- Demo link - https://blog.minhazav.dev/research/html5-qrcode.html
- QR Code decoding library - LazarSoft/jsqrcode
Want to read more such similar contents?
I like to write articles on topic less covered on internet. They revolve around writing fast algorithms, image processing as well as general software engineering.
I publish many of them on Medium.
If you are already on medium - Please join 4200+ other members and Subscribe to my articles to get updates as I publish.
If you are not on Medium - Medium has millions of amazing articles from 100K+ authors. To get access to those, please join using my referral link. This will give you access to all the benefits of Medium and Medium shall pay me a piece to support my writing!
Thanks!