THETA Photo Dog [THETA  Plug-in OLED活用]

#はじめに
リコーの[Yuuki_S](https://qiita.com/Yuuki_S)です。
弊社では[RICOH THETA](https://theta360.com/ja/)という全周囲360度撮れるカメラを出しています。
RICOH THETA VやTHETA Z1は、OSにAndroidを採用しており、Androidアプリを作る感覚でTHETAをカスタマイズすることもでき、そのカスタマイズ機能を「プラグイン」と呼んでいます。(詳細は本記事の末尾を参照）。
***
プラグイン開発ができるTHETAには、VとZ1の二種類があります。
このうち、Z1はフラッグシップ機。
1.0型裏面照射型CMOSイメージセンサーを搭載しRAW撮影も出来るスグレモノです。

これまでずっとVでプラグイン開発をしてきた自分ですが、ついにZ1を利用する機会がやってきました！
Z1を手にして、さて、どんなプラグインを作ろうかとまじまじと見比べてみます。
<img width="720" alt="3世代" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/152249/b7e5ed0d-df83-3afb-8fcb-cd62629791e9.jpeg">
左からZ1、V、Sです。
見て即座に分かるのは、レンズの大きさとディスプレイの有無。
Vでは詳細な状態を確認するためにスマホと繋げる必要がありましたが、Z1では本体のディスプレイで状態を確認できるのです。
ここはVとZ1の大きな違い！
なので、今回はこの有機ELディスプレイ(OLED)を使ったプラグインを作ることに決めました。


そして、出来上がったのがこちら↓

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">◤Qiita記事公開◢<br>表情豊か、THETA Photo Dog。<br>QRコードも表示できるTHETA Z1のディスプレイ表現力を試しました。<a href="https://t.co/Iwjcz8nMRG">https://t.co/Iwjcz8nMRG</a><a href="https://twitter.com/hashtag/THETA?src=hash&amp;ref_src=twsrc%5Etfw">#THETA</a> <a href="https://twitter.com/hashtag/thetaplugin?src=hash&amp;ref_src=twsrc%5Etfw">#thetaplugin</a> <a href="https://twitter.com/hashtag/3D%E3%83%97%E3%83%AA%E3%83%B3%E3%82%BF%E3%83%BC?src=hash&amp;ref_src=twsrc%5Etfw">#3Dプリンター</a> <a href="https://twitter.com/hashtag/blender?src=hash&amp;ref_src=twsrc%5Etfw">#blender</a> <a href="https://twitter.com/hashtag/%E7%8A%AC?src=hash&amp;ref_src=twsrc%5Etfw">#犬</a> <a href="https://twitter.com/hashtag/camera?src=hash&amp;ref_src=twsrc%5Etfw">#camera</a> <a href="https://t.co/vnTxsRFuE9">pic.twitter.com/vnTxsRFuE9</a></p>&mdash; THETAプラグイン開発者コミュニティ (@thetaplugin) <a href="https://twitter.com/thetaplugin/status/1329246144627568640?ref_src=twsrc%5Etfw">November 19, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

![コンポ 1.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/152249/c5b5a843-e7cd-64d3-0d64-a47b9315f931.gif)
![コンポ 1_3.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/152249/c2b4a860-79a1-1a78-f742-9caa0d399eaa.gif)
![コンポ 1_8.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/152249/fa2de8e3-532c-bfb9-509f-20b66e21d7a0.gif)
完全に一瞬の閃きから突っ走りました。
しかし、セルフタイマーのカウントダウンやQRコード表示等、ディスプレイがあることを最大限活用出来ているのではないでしょうか？

それでは、具体的な仕組みに関して触れていきましょう。

#仕組み紹介
![図1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/152249/f414691a-d9a7-1a86-d925-4771975d3435.png)
仕組みは至ってシンプルです。
プラグイン側には、”待機状態” "セルフタイマー” "QRコード表示”の3つの状態を用意しています。
前者2つでは所定のアニメーション画像を再生するようにし、最後のQRコード表示では生成したQRコードと事前準備したアニメーションを合成して表示しています。

3つの状態は、撮影ボタンもしくは犬の鼻部分を押すことで推移します。
この鼻部分、実は中にBluetoothリモートシャッターが組み込まれています。
なので押されるとBluetooth経由でシャッターが切られ、セルフタイマー表示に切り替わる仕組みです。

#プラグインからのOLED利用
THETAプラグイン開発者コミュニティでは過去にもOLEDの利用法を紹介しています。
[・RICOH THETA Z1の有機ELパネルをプラグインからコントロールする方法](https://qiita.com/ueue/items/3a1f0d7617f07dff6ec0)
[・THETA Z1 OLED描画ライブラリ的なものつくりました](https://qiita.com/KA-2/items/b16fd6adc6db7db0fb8e)

これらの記事はとても詳しく、今回と重複する内容もありますが、本記事では自分が試したOLED利用方法を記載します。

※開発には[RICOH THETA Plug-in SDK](https://github.com/ricohapi/theta-plugin-sdk)を利用します。初めての方はこちらの記事を参照してください
　→[THETAでRICOH THETA Plug-in SDKを動かす方法](https://qiita.com/yokazuya/items/cda20420ee0b1b58e03f)

さて、本題のOLED利用ですが画像を表示するだけなら以下を表示したいタイミングで呼ぶだけです。

```java
//imageはBitmap
notificationOledImageShow(image);
```
大変簡単ですが1点だけ注意点があり、画像の解像度は横128pixel、縦は36pixelもしくは24pixelである必要があります。
36pixelにすれば今回の様に全画面表示が可能です。
（全画面表示に対応するためには2019年10月24日に公開されたファームウェア Ver 1.20.1を導入する必要があります）

また、notificationOledImageShowはカラー画像を入れても動作しますが、Z1に搭載されているOLEDは白黒の2値表示しか出来ません。
なので、階調表現が削られ望み通りの見栄えにならない可能性もあります。

今回はそれを見越して、最初からアニメーション画像を2値ビットマップの状態でAdobe After Effectsにて作成しました。
以下の連番Bitmapをassetフォルダに配置し、描画用のスレッドを用意して順次切り替えています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/152249/1c8b5779-82b6-6d16-70f5-6d59a30207ff.png)
白黒2値の低解像度ディスプレイというと、たまごっちやPocketStation、ウォークマンのコントローラを思い出す世代ですが、今回初めて自分で2値画像を作ってみると奥が深いな、と感じました。
少ない解像度で伝えたいことを表現するって大変ですね。
(たまごっち、執筆のために調べたら鬼滅の刃バージョンが販売されてました。2値ドットでもキャラクターが表現されていて凄い...)




あと、今回は利用していませんが以下のようにすれば文字も表示可能です。

```java
Map<TextArea, String> output = new HashMap<>() ;
output.put(TextArea.MIDDLE, "Hello World !");
output.put(TextArea.BOTTOM, "This is output by the sample plugin.");
notificationOledTextShow(output);
```

なお、この他の複雑な利用に関しては、先程紹介した以下を利用すると便利になります。
[・THETA Z1 OLED描画ライブラリ的なものつくりました](https://qiita.com/KA-2/items/b16fd6adc6db7db0fb8e)

#QRコードの表示
待機中とセルフタイマー時のOLED表示は、画像をパラパラ漫画で表示するだけでしたが、最後のQRコードはプラグイン内で生成する必要があります。
実はこれも前述の記事”[THETA Z1 OLED描画ライブラリ的なものつくりました](https://qiita.com/KA-2/items/b16fd6adc6db7db0fb8e)"で紹介されています。
基本的な導入に関してはこちらを参照ください。

ただし、以前の記事では縦24pixelでQRコードを表示していました。
今回は、OLEDの全画面表示に対応しているファームウェア(1.20.1以降)を利用しているので、表示できるQRコードのサイズが大きくなり、表現できる情報量も増えています。

```java
 private void makeQrCode(String qrText) {
        int size = 36;
        try {
            BarcodeEncoder barcodeEncoder = new BarcodeEncoder();
            HashMap hints = new HashMap();
            hints.put(EncodeHintType.CHARACTER_SET, "shiftjis");
            hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.L);
            hints.put(EncodeHintType.QR_VERSION, 4);

            qrBitmap = barcodeEncoder.encodeBitmap(qrText, BarcodeFormat.QR_CODE, size, size,hints);
        } catch (WriterException e) {           
            e.printStackTrace();
        }
    }
```
QRコード生成部分は上記の通りで、誤り訂正レベルLにして画像サイズ36pixelにしています。
この状態でQRコードが持てる情報量はQRコードバージョン4の(英数記号含み)78文字になります。[(参考：QRコードの情報量とバージョン)](https://www.qrcode.com/about/version.html)
この長さならURLも埋め込むこと出来ます。

(また、試した所QRコードバージョン5 "37pixel x 37pixel" で画像生成し、リサイズしてOLEDに表示しても読み込むことが出来ました。1pixel分の情報が削られているはずなのですが、誤り訂正がうまく働いたのでしょう。)

そして、このQRコード生成処理に撮影画像アドレスを渡す部分は以下の通りで、撮影後のコールバック関数に含めています。

```java
    private TakePictureTask.Callback mTakePictureTaskCallback = new Callback() {
        @Override
        public void onTakePicture(String fileUrl)
        {           
            String fileUrl_replace = fileUrl.replace("127.0.0.1:8080","192.168.1.1");
            makeQrCodeVer(fileUrl_replace);
            FrameNum = 0;
            QRshowing = true;
        }
    };
```
ここで、fileUrl.replaceをおこなっています。
これはコールバックで得られるfileUrlを、APモードでアクセスできるURLに変更する処理です。
なお、今回はTHETAとスマートフォンが直接接続するAPモードのみを対象としています。
無線LANルータを挟んだCLモードへの対応は、いつかやりたい所です。

#Bluetoothの接続
Bluetoothリモートシャッターの接続は、以下のページが分かりやすいです。
[リモコンの使用方法（Z1/V/SC2）](https://www.thetalab.ricoh/howto/tips/remotecontroller/)

プラグイン起動前に接続しておけば、起動後も利用できます。
リモートシャッターの場合、シャッターボタンが押されるとKEYCODE_VOLUME_UPが発生するので、プラグイン側では以下のように検出することができます。

```java
  setKeyCallback(new KeyCallback() {
            @Override
            public void onKeyDown(int keyCode, KeyEvent event) {
                if (keyCode == KeyEvent.KEYCODE_VOLUME_UP) {
　　　　　　　　　～
```

#筐体の制作
ここまででプラグインの実装はほぼ完了です。
あとは筐体、犬部分の制作になります。
実は今回こちらの方が時間がかかりました。

まずノギス等使ってZ1の寸法を測り、Blenderで3Dモデルを作成します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/152249/33ba71eb-15e0-7e56-2a42-a5c4c3121639.png)
そして、それを軸に犬部分を作っていきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/152249/98003595-f7b1-d487-6f69-e5f278312aca.png)
この際、3Dプリントをすることを念頭にパーツ分けをおこなうのが重要です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/152249/2eb004dd-b23c-eccd-a6c0-87f32c6d0a00.png)
この分割したパーツそれぞれをSTL形式で出力し、印刷していきます。(全部で1日かかりました)
待ちながら、カラーリングを検討します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/152249/155e404d-cbab-dd44-0e7d-62757250892d.png)
印刷終えたら、組み上げて塗装です。
<img width="720" alt="絵の具" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/152249/8bd3a981-d6ac-1aac-c4e4-ca95a18e10e9.png">
今回はアクリル絵の具を利用しました。PLA素材にはアクリル絵の具がのりやすいのでオススメです。

#完成&まとめ
さて、これが完成した姿です。
![コンポ 2_1_1.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/152249/f7972de8-ef36-5107-aa8f-4ced1494a3d2.gif)
結構可愛く仕上がってるのではないでしょうか？

今回の記事では、THETA Z1のOLEDが全画面利用できることを紹介しました。
自由な画像を表示したり、QRコードを表示することでTHETA単独で出来ることの幅が広がります。

ぜひ、利用してみてください！


#RICOH THETAプラグインパートナープログラムについて 
THETAプラグインをご存じない方は[こちら](https://api.ricoh/products/theta-plugin/)をご覧ください。
パートナープログラムへの登録方法は[こちら](https://qiita.com/mShiiina/items/55d98f366e650ca42251)にもまとめてあります。
Qiitaの[RICOH THETAプラグイン開発者コミュニティ TOPページ「About」](https://qiita.com/organizations/theta-plugin)に便利な記事リンク集もあります。
興味を持たれた方は[Twitter](https://twitter.com/thetaplugin)のフォローと[THETAプラグイン開発コミュニティ(Slack)](https://join.slack.com/t/thetadeveloper/shared_invite/enQtNzcxODI2MTk2ODg0LWY5YmU2ZTIxNGYwNzlmNWZjMWMyMWFlMzY3ZmQ3NGU3ZjZiZjI0Njk4MGIxMDU5NDJiMzQ4Y2FkNDEzYmFlNGU)への参加もよろしくおねがいします｡