JavaScript
QRcode
QRコード

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

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

調査したライブラリ

GitHub :star: Star :fork_and_knife: Fork :arrow_down: downloads in the last month at npm Demo
LazarSoft/jsqrcode 2359 776 9664 or 796 https://webqr.com/
schmich/instascan 643 192 1698 https://schmich.github.io/instascan/
cozmo/jsQR 128 30 3456 https://cozmo.github.io/jsQR/
JodusNodus/react-qr-reader 146 43 10205 https://thomasbilliet.com/react-qr-reader/

LazarSoft/jsqrcode

ZXing というJavaのライブラリをJavaScriptに移植したものです。

このライブラリ自体はCommonJS形式で書かれていないのですが,別の方がCommonJS形式への変換とnpmの登録をしてくれていて,edi9999/jsqrcodevicapow/jsqrcode という2種類のプロジェクトがあります。

このライブラリはテストコードが不十分ということで,edi9999/jsqrcode の作者は,後述する cozmo/jsQR の利用を推奨しています。

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

schmich/instascan

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

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

cozmo/jsQR

最初からCommonJS形式で書かれていたり,テストコードがちゃんと書かれていたり,Typed Arrayが使われていたり,TypeScriptで記述されていたりと,モダンなライブラリとなっています。

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

JodusNodus/react-qr-reader

前述の cozmo/jsQR をReactコンポーネントとしてラップしたものです。Webカメラからの画像取得までやってくれるeasyなライブラリで,npmのダウンロード数の観点では一番人気があります。

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

これらのライブラリはモバイルDapp用に使えるか?

Status などのモバイルDappブラウザ上でQRコードが使えたら非常に便利なのですが,試してみたところ動作しませんでした。Statusの場合はReact Native上のWebViewを使っているので一筋縄ではいかないようです。もしかすると react-native-webview-bridge あたりに手を加える必要があるのかもしれません。

追記

まさにこの問題を解決するPull Requestが上がっていました!

react-native-webview-bridgeのPull Request を取り込むことでカメラにアクセスできるようになりそうです。近日中に取り込まれるようになるのではないでしょうか?