今回はSotaにQRコードを読み込ませてみる。
Sotaに何かしら入力をしたい場合に、QRコードを使うというのは結構あるので、実装の仕方が分かると便利だと思う。
公式のGithubのQRCodeTestクラスもあるが、たぶんこれだとうまく動かせないと思うので、改良してみた。
(そのうち修正するんじゃないかな)
環境はいつも通り。
対象 | OS、バージョン |
---|---|
PC | Windows10 x64 |
Sota | 1.4.0 |
VstoneMagic | 1.0.6047.29447(VstoneMagic_update20160803) |
VstoneMagicのSotaライブラリ | 1.4.0 |
VstoneMagicの操作方法等については、SotaでHelloWorldを参照。
今回のソースはここ。
QRコード読み込みクラスを作成する
QRcodeReaderクラスを作成する。
このクラスはテキストエディタで作成している。
QRコードはZXingを利用してデコードしている。
カメラオープン処理
まずは、QRコードを読み込ませるため、カメラをオープンする。
CameraCaptureクラスのインスタンスを生成し、openDeviceで「/dev/video0」(通常はこれがカメラデバイス)を指定する。
// VGAサイズのグレースケールでキャプチャするように設定
CameraCapture cap = new CameraCapture(CameraCapture.CAP_IMAGE_SIZE_VGA, CameraCapture.CAP_FORMAT_BYTE_GRAY);
// カメラデバイスをオープン
cap.openDevice("/dev/video0");
スナップ処理
snapメソッドでスナップし、RawtoBufferedImageでイメージデータを取得する。
cap.snap();
BufferedImage image = cap.RawtoBufferedImage();
デコード処理
イメージデータからBinaryBitmapを生成し、decodeメソッドでデコードした結果を取得する。
読み取ったコンテンツはgetTextメソッドで取得する。
LuminanceSource source = new BufferedImageLuminanceSource(image);
BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
// デコード
Reader reader = new MultiFormatReader();
Result result = reader.decode(bitmap);
// コンテンツ読み取り結果
content = result.getText();
QRコードが読み込めなかった場合にリトライをしたいので、スナップ処理とデコード処理をリトライできるようにしておく。
クローズ処理
最後にカメラデバイスをクローズする。
cap.close();
VstoneMagicでの実装
QRコード読み込みクラスをインポートする
VstoneMagicで新規ワークスペースを作成し、エクスプローラのjp.co.mysotaパッケージ以下に、QRコード読み込みクラスをインポートする。
右クリックメニュー > 追加 > クラスのインポート
で、さっき作成したQRcodeReader.javaを指定する。
リトライ回数用の変数宣言ブロックを用意
リトライ回数を設定する変数を用意する。
ツールボックス > プリミティブ > 変数宣言
をコンストラクタの中に入れる。
追加した変数宣言ブロックをダブルクリックし、ダイアログを表示する。
名前を「qrReadRetryCnt」とし、
initParamの値をダブルクリック > 定数入力:intの値に30
として、OKボタンをそれぞれ押してダイアログを閉じる。
OKボタンを押さないと反映されないので、気を付けること。
readQRCodeメソッドブロックの実装
メソッドブロックを追加する。
ツールボックス > プリミティブ > メソッドブロック
追加したメソッドブロックをダブルクリックし、methodNameを「readQRCode」とし、typeを「String」に設定する。このtypeは戻り値の値になるので、最終的にQRコード読み取り結果を返すように実装する。
readQRCodeメソッドブロックに、変数宣言ブロックを追加し、名前を「content」、typeを「String」、initParamをnullとする。
returnブロックを追加する。
ツールボックス > プリミティブ > return
追加したreturnブロックをダブルクリックし、ダイアログを表示する。
returnValueの値をダブルクリックし、変数選択から「content」(さっき追加した変数)を選択する。
OKボタンをそれぞれ押して、ダイアログを閉じる。
自由記述処理ブロックを追加する
ツールボックス > RobotLib > 自由記述処理
自由記述処理ブロックは、その名の通り、自由にコードを記述することが出来る。
ただのテキストボックスなので、スペルミスに気付かなかったり、どこに何が実装されているか分からなくなるので、あまり多用しないようにする方が良いと思う。
今回は、QRcodeReaderクラスのインスタンスを生成し、readメソッドを呼び出す処理を記述する。
追加した自由記述処理ブロックをダブルクリックし、textsの値をダブルクリックする。
下記を記述する。
QRcodeReader reader = new QRcodeReader();
content = reader.read(qrReadRetryCnt);
メインメソッドの実装
mainメソッドブロックに、QRコード読み込み前に発話(ここでは「20センチくらい離した位置で、QRコードを見せてね」としている)ブロックを追加し、QRコード読み込み結果のコンテンツを受け取る変数宣言ブロック(content)を追加する。
readQRCodeメソッドブロックを追加する。
エクスプローラ > mymainクラス > readQRCodeメソッド
追加したreadQRCodeメソッドブロックを選択し(ダブルクリックではダイアログは表示されない)、プロパティのenableGetReturnの値を「True」(デフォルトではfalseになっている)に変更し、recvVariableの値に「content」(さっき追加した変数)を選択する。
QRコード読み取り結果のコンテンツをとりあえず発話させてみる。
発話ブロックを追加し、発話内容をcontentに設定する。
実行すると、発話 > QRコード読み取り > 結果を発話 という流れになる。
QRコード読み取り結果のコンテンツがnullだと、QRコード読み取りに失敗した扱いなので、分岐させて処理すると良いと思う。