Android アプリ開発「MATRIX」

Androidアプリの開発に役立つサンプル集

【Android開発】CameraX にマニュアルフォーカス機能を追加する方法 - Kotlin

今回は CameraX にマニュアルフォーカス機能を追加する方法を解説します。これから CameraX でカメラアプリを作ろうと考えている方は、ぜひこちらを参考にして時間を節約してください。

※なお、CameraX によるカメラアプリの基本ベースは、以下の2つの記事を参考としていただければと思います。

android-java.hatenablog.jp

android-java.hatenablog.jp

~ ポイント説明 ~

CameraX にマニュアルフォーカス機能を追加する方法は、過去の記事のズーム機能を追加する方法によく似ていますが、今回は Camera2 のカメラコントロール機能を追加するため、処理がやや難しくなります。

★必須となる追加処理は以下の3点です。

  1. オートフォーカスを「OFF」にする
  2. CaptureRequestOptions を作成する
  3. Camera2CameraControl2 をセットする

それでは、手順を詳しくご説明します。

~ 手順 ~

① Camera、CameraControl、CaptureRequestOptions、CaptureRequestOptions.Builder を宣言します。

private lateinit var camera: Camera
private lateinit var cameraControl: CameraControl
private lateinit var captureRequestOptions: CaptureRequestOptions
private lateinit var captureRequestOptionsBuilder: CaptureRequestOptions.Builder

② Camera から CameraControl を取得します。Camera(camera) は プレビューを開始する fun { } の中ので取得することができます。

camera = cameraProvider.bindToLifecycle(
          this,
          cameraSelector,
          preview,
          imageCapture,
          videoCapture
)
//CameraControl 取得
cameraControl = camera.CameraControl

③ CameraControl を取得後、続けて「Camera2CameraControl」も取得します。

camera2CameraControl = Camera2CameraControl.from(camera.cameraControl)

④ CaptureRequestOptionsBuilder に、オートフォーカスモードのOFFと、焦点距離の設定値(下の例は float値で2.0f)の2つのリクエストをセットして、最後にビルドします。

captureRequestOptionsBuilder.setCaptureRequestOption(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_OFF)
captureRequestOptionsBuilder.setCaptureRequestOption(CaptureRequest.LENS_FOCUS_DISTANCE, 2.0f)
captureRequestOptions = captureRequestOptionsBuilder.build() //ビルド

⑤ ③ で取得した Camera2CameraControl に ④ で作成したCaptureRequestOptions をセットすると、この時点でマニュアルフォーカスが実行されます。

camera2CameraControl.setCaptureRequestOptions(captureRequestOptions)

~ ボタンと連動する場合の例 ~

ボタンと連動させる場合は以下のようにします。

var focus: Float = 0.0f

//フォーカスを0.1手前に移動する
viewBinding
.focusButtonPlus.setOnClickListener {
  focus += 0.1f
manual_focus()
}

//フォーカスを0.1奥に移動する
viewBinding.focusButtonMinus.setOnClickListener {
  focus -= 0.1f
   manual_focus()
}

//マニュアルフォーカスの実行
private fun manual_focus() {
   captureRequestOptionsBuilder.setCaptureRequestOption(CaptureRequest.LENS_FOCUS_DISTANCE, focus)
captureRequestOptions = captureRequestOptionsBuilder.build()
camera2CameraControl.setCaptureRequestOptions(captureRequestOptions )

}

リクエストできる焦点距離(下の例では focus)は、「0.0 ~ レンズの最短焦点距離」で、最短焦点距離はカメラ特性(CameraCharacteristics.LENS_INFO_MINIMUM_FOCUS_DISTANCE)で取得できます。

なお、焦点距離は 0.0 が最も遠くにピントが合い、数値が高くなるほど近くの被写体にピントが合う接写になります。

ちなみに、管理人が使用しているテスト端末(SHARP S5-SH)の背面レンズの最短焦点距離は 10.0 でした。

備考・まとめ

最近のスマートフォンには複数のレンズが搭載されていますが、フロントカメラや超ワイドレンズはマニュアルフォーカスに対応していない場合が多いので、ぜひご注意願います。

今後は、スライダーとピンチ動作でズーム率を変更する方法などをご紹介する予定です。

それでは・・・m(_ _)m

END