Camera2APIでカメラプレビュー中に光センサーの値によってライトを自動でON/OFFにする

Posted by kwmt27 on Fri, Jul 30, 2021

はじめに

  1. Camera2APIを使って、カメラプレビュー中に(フラッシュではなく)ライトをONにできるのか?
  2. 周りが暗くなったら自動でライトをONにできるか?

というのが気になって調べたのでメモしておく。

camera-samplesをベースに試した全体的なコードはこちら。 https://github.com/kwmt/camera-samples/pull/1/

1. Camera2APIを使って、カメラプレビュー中に(フラッシュではなく)ライトをONにできるのか?

調べている中で、ライトのことをTorch Modeというらしいことを知った。

まず目に入ったのが、CameraMangaer#setTorchModeというメソッドで、これを(ドキュメントを読まずに^^;)試してみたら(カメラプレビュー中にコールする)、CAMERA_IN_USEという例外がスローされてしまう。

これはよくよくドキュメントを見ると

Set the flash unit’s torch mode of the camera of the given ID without opening the camera device.

カメラデバイスを開かずに、指定されたIDのカメラのフラッシュユニットのトーチモードを設定します。

とあり、カメラプレビュー中ということはカメラをopenしている状態なので、openしてない場合に使えるメソッドであることがわかった。

別の方法を検討する。

こちらのstackoverflowで次のようなことを見つけた。 https://stackoverflow.com/a/57331014/2520998

Once the camera is open, you can use FLASH_MODE and set it to TORCH in your preview capture request. This means you need to keep AE_MODE to either ON or OFF, not one of the FLASH modes, so that auto-exposure isn’t controlling the flash.

カメラを開いたら、FLASH_MODEを使用して、プレビューキャプチャ要求でTORCHに設定することができます。 つまり、自動露出がフラッシュを制御しないように、AE_MODEをFLASHモードではなく、ONまたはOFFにしておく必要があります。

camera-samplesのこの部分を次のように変更してみる。

val captureRequest = camera.createCaptureRequest(
        CameraDevice.TEMPLATE_PREVIEW).apply { addTarget(fragmentCameraBinding.viewFinder.holder.surface) }

+ captureRequest.set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_ON)
+ captureRequest.set(CaptureRequest.FLASH_MODE, CaptureRequest.FLASH_MODE_TORCH)
// This will keep sending the capture request as frequently as possible until the
// session is torn down or session.stopRepeating() is called
session.setRepeatingRequest(captureRequest.build(), null, cameraHandler)

これを実行すると、カメラプレビュー中にライトをONにすることができた。

2. 周りが暗くなったら自動でライトをONにできるか?

つぎに、周りが暗くなったら自動でライトをONにできるか?については、問題を2つに分ける。

  • 光センサーで光量を測定できるか?
  • 動的にライトをON/OFFできるか?

光センサーで光量を測定できるか?

光センサーが搭載されているので、光センサーからデータをモニタリングすることができる。公式ドキュメントにそのままのコードがあるので、参考にする。

https://developer.android.com/guide/topics/sensors/sensors_overview?hl=ja#sensors-monitor

camera-samplesで試したコードはこちら。

動的にライトをON/OFFできるか?

こちらの、タッチしたときにCaptureRequestBuilderをリビルドしていたのがヒントになった。

上記で光量を検知できたので、適当なしきい値を決めて、そのしきい値より小さければOFF、しきい値以上ならONにするには、次のようにCaptureRequestBuilderを設定しなおしてリビルドすればよい。

まとめ

  • Camera2APIを使って、カメラプレビュー中に(フラッシュではなく)ライトをONにするには、CaptureRequest.BuilderでCONTROL_AE_MODECONTROL_AE_MODE_ONにしてからFLASH_MODEFLASH_MODE_TORCHにセットする。
  • 周りが暗くなったら自動でライトをONにするには、光センサーで光量を取得できるので、しきい値を設定してCaptureRequest.BuilderにCONTROL_AE_MODE_ONCONTROL_AE_MODE_OFFにセットし直してbuildする。

次の動画は、周りが暗い状態(夜の部屋)で、カメラプレビュー中に電気を消して暗くしたらライトがONし、電気をつけるとライトがOFFになる動画です。



comments powered by Disqus