Skip to content

Commit

Permalink
Merge pull request #24 from mebjas/file-support
Browse files Browse the repository at this point in the history
Added support for local file QR Code scanning
  • Loading branch information
mebjas authored Apr 18, 2020
2 parents 79a655b + 5a6645f commit 51dd856
Show file tree
Hide file tree
Showing 11 changed files with 480 additions and 45 deletions.
104 changes: 94 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
# Html5-QRCode
A cross-platform HTML5 QR code reader.
Use this light-weight Javascript library `(52 Kb)` to add QR Code scanning capability in your web application.
Use this light-weight Javascript library `(56 Kb)` to add QR Code scanning capability in your web application.
- Supports easy scanning using web-cam or camera in the smartphones (Android / IOS).
- **Recently Added** Scanning QR Code from files or default camera on smartphones.

> Support for scanning local files on the device is a new addition and helpful for the web browser which do not support inline web-camera access in smartphones. **Note:** This doesn't upload files to any server - everything is done locally.
[![GitHub issues](https://img.shields.io/github/issues/mebjas/html5-qrcode)](https://github.com/mebjas/html5-qrcode/issues) [![GitHub tag (latest by date)](https://img.shields.io/github/v/tag/mebjas/html5-qrcode)](https://github.com/mebjas/html5-qrcode/releases) ![GitHub](https://img.shields.io/github/license/mebjas/html5-qrcode)

Expand All @@ -10,8 +14,8 @@ Use this light-weight Javascript library `(52 Kb)` to add QR Code scanning capab
Working on adding support for more and more platforms. If you find a platform or browser where the library is not working please feel free to file an issue. Check the [demo link](https://blog.minhazav.dev/research/html5-qrcode.html) to test out.

##### Legends
- ![](assets/done.png) Means supported
- ![](assets/progress.png) Means work in progress to add support
- ![](assets/done.png) Means full support - inline webcam and file based
- ![](assets/partial.png) Means partial support - only file based, webcam in progress

### PC / Mac

Expand All @@ -23,13 +27,13 @@ Working on adding support for more and more platforms. If you find a platform or

| <img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/chrome/chrome_48x48.png" alt="Chrome" width="24px" height="24px" /><br/>Chrome | <img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/firefox/firefox_48x48.png" alt="Firefox" width="24px" height="24px" /><br/>Firefox | <img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/edge/edge_48x48.png" alt="Edge" width="24px" height="24px" /><br/> Edge | <img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/opera/opera_48x48.png" alt="Opera" width="24px" height="24px" /><br/>Opera | <img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/opera-mini/opera-mini_48x48.png" alt="Opera-Mini" width="24px" height="24px" /><br/> Opera Mini | <img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/uc/uc_24x24.png" alt="UC" width="24px" height="24px" /> <br/> UC
| --------- | --------- | --------- | --------- | --------- | --------- |
|![](./assets/done.png)| ![](assets/done.png)| ![](assets/done.png)| ![](assets/done.png)| ![](assets/progress.png) | ![](assets/progress.png)
|![](./assets/done.png)| ![](assets/done.png)| ![](assets/done.png)| ![](assets/done.png)| ![](assets/partial.png) | ![](assets/partial.png)

### IOS

| <img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/safari-ios/safari-ios_24x24.png" alt="Safari" width="24px" height="24px" /><br/>Safari | <img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/chrome/chrome_48x48.png" alt="Chrome" width="24px" height="24px" /><br/>Chrome | <img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/firefox/firefox_48x48.png" alt="Firefox" width="24px" height="24px" /><br/>Firefox | <img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/edge/edge_48x48.png" alt="Edge" width="24px" height="24px" /><br/> Edge
| --------- | --------- | --------- | --------- |
|![](./assets/done.png)| ![](assets/progress.png)| ![](assets/progress.png)| ![](assets/progress.png)
|![](./assets/done.png)| ![](assets/partial.png)| ![](assets/partial.png)| ![](assets/partial.png)

> Apparently, Webkit for IOS is used by Chrome, Firefox, and other browsers in IOS and they do not have webcam permissions yet. There is an ongoing issue on fixing the support for iOS - [issue/14](https://github.com/mebjas/html5-qrcode/issues/14)
Expand All @@ -40,7 +44,7 @@ This is a cross-platform javascript library to create a QRcode reader for HTML5

Supports:
- Querying all camera in the device (With user permissions)
- Using any camera for scanning QR Code.
- Using any camera for scanning the QR Code.

## How to use?
> For full information [read this article](https://blog.minhazav.dev/HTML5-QR-Code-scanning-launched-v1.0.1/).
Expand All @@ -56,7 +60,7 @@ Add an element you want to use as placeholder for QR Code scanner
```

Add `minified/html5-qrcode.min.js` in your web page.
> I would recommend using the minified version as it's transformed to standard javascript. The `html5-qrcode.js` is written with ECMAScript and may not be supported in older version of the browsers. I wrote in this as it's easier to maintain!
> I would recommend using the minified version as it's transformed to standard javascript. The `html5-qrcode.js` is written with ECMAScript and may not be supported in the older version of the browsers. I wrote in this as it's easier to maintain!
```html
<script src="./minified/html5-qrcode.js"></script>
Expand All @@ -67,6 +71,8 @@ Add `minified/html5-qrcode.min.js` in your web page.
-->
```

### For using inline QR Code scanning with Webcam or Smartphone camera

To get a list of supported cameras, query it using static method `Html5Qrcode.getCameras()`. This method returns a `Promise` with list of devices supported in format `{ id: "id", label: "label" }`.
```js
// This method will trigger user permissions
Expand Down Expand Up @@ -112,14 +118,67 @@ html5QrCode.stop().then(ignore => {
// Stop failed, handle it.
});
```

> Note that the class is stateful and `stop()` should be called to properly tear down the video and camera objects safely after calling `start()` when the scan is over or user intend to move on. `stop()` will stop the video feed on the viewfinder.
### For QR Code scanning using local files or inbuild camera on Smartphones
| Selector in Android | Selector in IOS|
|------|-------|
| Taken on Pixel 3, Google Chrome<br><img src="./assets/selector_android.png" width="300px"> | Taken on iPhone 7, Google Chrome<br><img src="./assets/selector_iphone.jpg" width="300px"> |

You can alternatively leverage QR Code scanning for local files on the device or default camera on the device. It works similar to inline QR Code scanning.

Define the HTML container and import the javascript library as mentioned above
```html
<div id="reader"></div>
<script src="./minified/html5-qrcode.js"></script>
```

Add an `Input` element for supporting file selection like this:
```html
<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 this at [developers.google.com](https://developers.google.com/web/fundamentals/media/capturing-images).

And in javascript code initialize the object and attach listener like this:
```js
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;
}

const imageFile = e.target.files[0];
// Scan QR Code
html5QrCode.scanFile(imageFile, true)
.then(qrCodeMessage => {
// success, use qrCodeMessage
console.log(qrCodeMessage);
})
.catch(err => {
// failure, handle it.
console.log(`Error scanning file. Reason: ${err}`)
});
});
```

> 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.
## Demo
[blog.minhazav.dev/research/html5-qrcode.html](https://blog.minhazav.dev/research/html5-qrcode.html)

### For more information
Check this article on how to use this library [HTML5 QR Code scanning - launched v1.0.1 without jQuery dependency and refactored Promise based APIs](https://blog.minhazav.dev/HTML5-QR-Code-scanning-launched-v1.0.1/).

## Screenshots
![screenshot](assets/screen.jpg)<br>
![screenshot](assets/screen.png)<br>
_Figure: Screenshot from Google Chrome running on Macbook Pro_

## Documentation
Expand Down Expand Up @@ -186,19 +245,44 @@ class Html5Qrcode {
* @returns Promise for safely closing the video stream.
*/
stop() {} // Returns a Promise

/**
* 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, /* default=true */ showImage) {}

/**
* Clears the existing canvas.
*
* Note: in case of ongoing web cam based scan, it needs to be explicitly
* closed before calling this method, else it will throw exception.
*/
clear() {} // Returns void
}
```

### Extra optional `configuration` in `start()` method
This is a configuration for the QR code scanning which can effect both scanning behavior and UI. There are two optional properties right now, if you don't want them you can just pass an empty object `{}`.

#### `fps` - Integer, Example = 10
A.K.A frame per seconds, the default value for this is 2 but it can be increased to get faster scanning. Increasing too high value could affect performance. Value `>1000` will simply fail.
A.K.A frame per second, the default value for this is 2 but it can be increased to get faster scanning. Increasing too high value could affect performance. Value `>1000` will simply fail.

#### `qrbox` - Integer, Example = 250
Use this property to limit the region of the viewfinder you want to use for scanning. The rest of the viewfinder would be shaded. For example by passing config `{ qrbox : 250 }`, the screen will look like:

<img src="./assets/screen.jpg" width="450px">
<img src="./assets/screen.png" width="450px">

If you do not pass any value, the whole viewfinder would be used for scanning.
**Note**: this value has to be smaller than the width and height of the `QR code HTML element`.
Expand Down
Binary file added assets/partial.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file removed assets/progress.png
Binary file not shown.
Binary file removed assets/screen.jpg
Binary file not shown.
Binary file added assets/screen.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/selector_android.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/selector_iphone.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading

0 comments on commit 51dd856

Please sign in to comment.