JavaScriptでQRコードをスキャンするライブラリまとめ

QRコードをブラウザで読み取ることができるJavaScriptのライブラリを調査しました。

## 調査したライブラリ

| GitHub | :star: Star | :fork_and_knife: Fork | :arrow_down: downloads in the last month at npm | Demo |
| ------ | ----------: | --------------------: | -------------------------------------------------: | ----- |
| [LazarSoft/jsqrcode](https://github.com/LazarSoft/jsqrcode) | 3.3k | 1k | [6344](https://www.npmjs.com/package/qrcode-reader) or [44](https://www.npmjs.com/package/jsqrcode) | https://webqr.com/ |
| [schmich/instascan](https://github.com/schmich/instascan) | 2k | 636| [181](https://www.npmjs.com/package/instascan) | https://schmich.github.io/instascan/ |
| [cozmo/jsQR](https://github.com/cozmo/jsQR) | 1.5k | 241 | [14547](https://www.npmjs.com/package/jsqr) | https://cozmo.github.io/jsQR/ |
| [JodusNodus/react-qr-reader](https://github.com/JodusNodus/react-qr-reader) | 527 | 149 | [5351](https://www.npmjs.com/package/react-qr-reader) | https://thomasbilliet.com/react-qr-reader/ |

## [LazarSoft/jsqrcode](https://github.com/LazarSoft/jsqrcode)

[ZXing](https://github.com/zxing/zxing) というJavaのライブラリをJavaScriptに移植したものです。

このライブラリ自体はCommonJS形式で書かれていないのですが，別の方がCommonJS形式への変換とnpmの登録をしてくれていて，[edi9999/jsqrcode](https://github.com/edi9999/jsqrcode) と [vicapow/jsqrcode](https://github.com/vicapow/jsqrcode) という2種類のプロジェクトがあります。

このライブラリはテストコードが不十分ということで，[edi9999/jsqrcode](https://github.com/edi9999/jsqrcode) の作者は，後述する [cozmo/jsQR](https://github.com/cozmo/jsQR) の利用を推奨しています。

このライブラリは画像ファイルのDataURLからQRコードを読み込むところまでを対象としているので，Webカメラから画像を取得する処理は [navigator.getUserMedia](https://developer.mozilla.org/ja/docs/Web/API/Navigator/getUserMedia) などを使って自分で書く必要があります。参考事例を2つ挙げておきます。

* [ブラウザからQRコードデコード - Qiita](https://qiita.com/tkyk0317/items/7d7f327cda48086f894f)
* [ネイティブアプリ不要！モバイルWebサイトにQRコードリーダーを実装する方法 - WPJ](https://www.webprofessional.jp/create-qr-code-reader-mobile-website/)

## [schmich/instascan](https://github.com/schmich/instascan)

前述の [LazarSoft/jsqrcode](https://github.com/LazarSoft/jsqrcode) のもととなったライブラリである [ZXing](https://github.com/zxing/zxing) というJavaのライブラリをC++に移植した [zxing-cpp](https://github.com/glassechidna/zxing-cpp) をEmscriptenでJavaScriptに変換した [zxing-cpp-emscripten](https://github.com/kig/zxing-cpp-emscripten) のラッパーです（長い）。

このライブラリはWebカメラからの画像の取得までやってくれるようなのですが，READMEにはiOS Safariには対応していないという旨のことが書いてあります。これは，iOS Safariで `navigator.getUserMedia` が使えるようになったのが最近のこと（iOS11以降）だからです。 ~~もしかすると現在のiOS Safariでは普通に使えるのかもしれません（手元にiOSが無いので検証できません）。~~ @syoyo さんの検証によるとiOS11でも動作しなかったようです。以下のPRが取り込まれていないのを見ても分かるように，最近は開発が停滞気味です。

* https://github.com/schmich/instascan/pull/78
* https://github.com/schmich/instascan/pull/112

## [cozmo/jsQR](https://github.com/cozmo/jsQR)

最初からCommonJS形式で書かれていたり，テストコードがちゃんと書かれていたり，Typed Arrayが使われていたり，TypeScriptで記述されていたりと，モダンなライブラリとなっています。npmのダウンロード数の観点では最も人気があります。

使い方は画像データを [ImageData](https://developer.mozilla.org/en-US/docs/Web/API/ImageData) 形式で準備してから `jsQR(imageData, width, height)` に渡すだけというシンプルなインターフェースになっていますが，これもjsqrcodeと同様にWebカメラから画像を取得する処理は自分で書く必要があります。

## [JodusNodus/react-qr-reader](https://github.com/JodusNodus/react-qr-reader)

前述の [cozmo/jsQR](https://github.com/cozmo/jsQR) をReactコンポーネントとしてラップしたものです。Webカメラからの画像取得からQRコードのデコードまでやってくれるeasyなライブラリです。

jsQRでQRコードをスキャンする処理はCPUで行われるので，シングルスレッドで駆動するJavaScriptにとって苦手な処理なのですが，このライブラリではjsQRでの処理をWeb Workerで別スレッドにオフロードすることでUIスレッドへの影響を小さくしています。