HTML5 QR Code scanning with javascript - Support for scanning the local file and using default camera added (v1.0.5)
html5-qrcode helps developer to integrate QR code scanning in HTML5 based applications. It abstracts camera access and usage on different browsers and simplify QR Code scanning for developers. The primary goal of the library is cross-platform support across different OS versions and Browsers. One of the key problems with cross-platform support was some browsers in Android and many browsers in iOS (almost all other than Safari which are based on WebKit for iOS) did not support camera access. This prevents users from doing inline QR Code scanning which is the primary feature of the library. To mitigate this I have added support for scanning local media on the device and it implicitly adds support for capturing QR Code using default camera on the device and scanning it. This is an upgrade to the existing library - you can read more about it here. In this article I have explained now file-based scanning works and how to use it.
Changelog
- Added support for scanning local images on the device.
- Added support for capturing an image using the camera on the phone and scanning it.
- Added API to clear existing canvas.
The library has been updated to npm and a v1.0.5 is released in Github.
Great thing is - this extends the library to work on almost all OS types and browsers.
Demo
A demo for this project is hosted at blog.minhazav.dev/research/html5-qrcode.html
Issue with inline scanning
If you look at the issue 14 on the Github project
Compatibility - [ios] [All Browser] - [Query Camera]
Query camera is not working for Opera, Edge, Firefox and Chrome. OS: iOS in Iphone 7 and IPad 9.7
The root cause for this was an issue in Webkit for IOS which is used by almost all these browsers in IOS. The issue was - it doesn’t permit browsers other than Safari to access Camera on the device. Check this StackOverflow question for more info. This is very sly and has been there for many years with no progress. To make sure this library can be used cross-platform I have added a fallback type approach which allows users to either capture the QR Code using default camera or load a media from disk. This solution is not perfect but can be used to have good support for QR Scanning in the app.
You can use it something like this:
Figure: QR Code scanning with both the inline viewfinder and file scanning option.
How this works
HTML5 supports input
type file
which allow accessing files locally using javascript with user consent. Adding capture
tag can be used to restrict the option to capture using a camera alone for Android and IOS while it is ignored in PC browsers. When a user clicks on the file input following types of dialogs are shows in different OS:
Selector in Android | Selector in IOS |
---|---|
Taken on Pixel 3, Google Chrome | Taken on iPhone 7, Google Chrome |
How to use
Apart from the standard steps described here like:
Include the library
<script
src="https://raw.githubusercontent.com/mebjas/html5-qrcode/master/minified/html5-qrcode.min.js">
</script>
Add placeholder element
<div id="reader"></div>
Add input
of type file
<input type="file" id="qr-input-file" accept="image/*">
<!--
Or add captured if you only want to enable smartphone camera, PC browsers will ignore it.
-->
<input type="file" id="qr-input-file" accept="image/*" capture>
Find more information about input tags at developers.google.com.
Use Html5Qrcode#scanFile()
API to scan an image File
.
The new API looks like this:
/**
* Scans an Image File for QR Code.
*
* This feature is mutually exclusive to camera based scanning, you should call
* stop() if the camera based scanning was ongoing.
*
* @param {File} imageFile a local file with Image content.
* @param {boolean} showImage if true the Image will be rendered on given element.
*
* @returns Promise with decoded QR code string on success and error message on failure.
* Failure could happen due to different reasons:
* 1. QR Code decode failed because enough patterns not found in image.
* 2. Input file was not image or unable to load the image or other image load
* errors.
*/
scanFile(imageFile, showImage /* default = true */) {}
imageFile
is of typeFile
. It’s the argument which you get fromchange
lisntener on the<input type='file' />
.showImage
is an optional boolean argument, with default value =true
. If this is true the library will render the user image on<div id="reader"></div>
, otherwise not.
This is a Promise
based API which returns the decoded QR Code message on success and error message on failure. The error could happen at different levels like image loading or QR Code scanning.
And in javascript code initialize the object and attach listener like this:
const html5QrCode = new Html5Qrcode(/* element id */ "reader");
// File based scanning
const fileinput = document.getElementById('qr-input-file');
fileinput.addEventListener('change', e => {
if (e.target.files.length == 0) {
// No file selected, ignore
return;
}
// Use the first item in the list
const imageFile = e.target.files[0];
html5QrCode.scanFile(imageFile, /* showImage= */true)
.then(qrCodeMessage => {
// success, use qrCodeMessage
console.log(qrCodeMessage);
})
.catch(err => {
// failure, handle it.
console.log(`Error scanning file. Reason: ${err}`)
});
});
Important
Note that inline scanning and file-based scanning are mutually exclusive at the moment. This means, you can only use one of them at a time. I’ll soon be adding support for the option to have both if the requirement comes in. If you want to use both, use html5QrCode#clear() method to clear the canvas.
Clearing the canvas after use
Since unlike the inline scanning this API doesn’t support start()
and stop()
you can use:
html5QrCode.clear();
API to clear the canvas after use.
My recommendation
Add support for both inline scanning and file-based approach in your app like shown in the demo. This will allow users to use which ever works for them irrespective of the browser they are on.
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!