はじめに
先日、iPhoneのカメラアプリでは読み込めるQRコードがVue用のライブラリであるVue Qrcode Readerではなかなか反応しないという問題がありました。
iOSアプリとしてWKWebView上で使用する部分での事でしたが、実際にサービスで対象とするQRコードが約1cm四方のサイズで、当初の想定よりも小さかったため、問題の発覚が遅れるといった状況が発生しました。
結果として、QrcodeStreamのPropsにconstraintsを明示的に記述することでカメラの解像度が上がり、対処することができました。
その際に調べた内容について書いていきたいと思います。
Vue Qrcode ReaderのQrcodeStream
QrcodeStreamはgetUserMedia/Stream API、barcode-detectorを利用してリアルタイムでカメラ動画からQRコードを検出します。
- カメラ起動の際にcapabilitiesを取得
- constraintsを指定
- バーコードのformatsを指定
- detectのイベントで検出結果の各内容を取得
というような形でシンプルにQRコード検出の実装が行えます。
capabilities(能力)
@camera-onのイベントでMediaTrackCapabilitiesとして取得することができます。
この内容で起動しているカメラのconstraintsにおいての指定範囲が把握可能です。
constraints(制約)
constraintsはどちら向きのカメラか、サイズ、フレームレートなどの制約をMediaTrackConstraintsの内容でpropとして記述します。
propとして記述しない場合はデフォルトとしてリアカメラが利用される制約のみとなります。
constraintsの内容が変わるとcamera-onのイベントが再度呼ばれます。
扱われる型について
ConstrainBoolean、ConstrainDouble、ConstrainDOMString、ConstrainULong等これらは直接プリミティブのbooleanやnumber、stringとしても扱えますが、以下のプロパティを持つオブジェクトしても扱うことができます。
- ideal
- 理想的な値
- exact
- 厳密に要求する値
また、numberを扱うものでは
- max
- 最大許容値
- min
- 最小許容値
も指定することができます。
constraintsの各内容でidealが指定されている場合、機器が該当しないケースでは制約された内容に近いものが利用されます。
idealの指定がなく機器が該当しない場合にはエラーとなります。
ちなみに、プリミティブ型として扱った場合にはidealの指定がされている場合と同等の挙動となっています。
試した対応内容
- @camera-onで取得したcapabilitiesのwidth.max、height.maxを保持
- constraintsのwidthとheightに反映させる
<QrcodeStream :paused="isPauseCamera" @detect="onDetect" @error="onError" @camera-on="onReady" :constraints="{
facingMode: ['environment'],
width: { ideal: targetMaxWidth },
height: { ideal: targetMaxHeight }
}" />
としたところ、検出の精度が大幅に改善され、detectイベントで取得できるboundingBoxのサイズも数倍の大きさとなっていることが確認できました。
実装時のちょっとした注意点ですが、検証に使用したiPhoneではconstraintsを明示的に指定すると、facingModeは記述がない限り’user’として扱われていました。
リアカメラを使用する場合では明示的に’environment’を指定する必要がありました。
カメラの指定
余談ですが、使用できる機器の取得はMediaStream APIのMediaDevices: enumerateDevices()で行えます。
フロントカメラ、リアカメラ以上の指定を行いたいような場合には、使用するカメラのリスト上のdeviceIdをconstraintsで指定するという対応となります。
まとめ
シンプルな対応でVue Qrcode Readerにてカメラの解像度を上げることができました。
最初から大きいサイズではないことにはそれなりの意味はあるかと思いますが、使用箇所が限定されているようなケースでは今回のような対応を行うのは十分価値があると考えられます。
もし同じような問題で困っている方がいれば、お力になれたら嬉しいです。
参考
- Vue Qrcode Reader
- barcode-detector
- 能力と制約と設定
- MediaTrackCapabilities
- 4.3.6 MediaTrackConstraints
- MediaDevices: enumerateDevices() メソッド








