ユースケースの動作のさまざまな要素を制御するには、設定インターフェース クラスを使用して CameraX の各ユースケースを設定します。
たとえば、画像キャプチャ ユースケースでは、使用するレンズ、ターゲット アスペクト比、スレッド化の方法を設定できます。次のコードはその一例を示しています。
Kotlin
val config = ImageCaptureConfig.Builder() .setLensFacing(...) .setFlashMode(...) .setTargetAspectRatio(...) .build()
Java
ImageCaptureConfig config = new ImageCaptureConfig.Builder() .setLensFacing(...) .setFlashMode(...) .setTargetAspectRatio(...) .build();
一部のユースケースでは、設定オプションに加えて、ユースケースの作成後に設定を動的に変更する API も公開しています。各ユースケースに固有の設定については、プレビューを実装する、画像を解析する、写真を撮るをご覧ください。
自動選択
CameraX は、アプリが実行されているデバイスに固有の機能を自動的に提供します。たとえば、解像度を指定していない場合や、指定した解像度がサポートされていない場合、使用する最適な解像度を自動的に決定します。こうした処理はすべてバックグラウンドで行われるため、デバイスに固有のコードを作成する必要はありません。
CameraX の目標は、カメラ セッションを正常に初期化することです。そのために、CameraX はデバイス機能に基づいて解像度とアスペクト比を低下させることがあります。これは、次の理由で発生する可能性があります。
- デバイスが要求される解像度をサポートしていません。
- デバイスに互換性の問題があります。たとえば、古いデバイスの中には、正常に動作するために特定の解像度を必要とするものがあります。
- 一部のデバイスでは、特定のアスペクト比でのみ使用可能な特定の形式があります。
- デバイスで、JPEG または動画エンコードについて「mod16 に最も近い」値が優先されます。詳しくは、SCALER_STREAM_CONFIGURATION_MAP をご覧ください。
CameraX はセッションを作成および管理しますが、コードのユースケース出力で返される画像サイズを常に確認し、それに応じて調整する必要があります。
回転
カメラの回転はデフォルトでは、ユースケースの作成時にデフォルトのディスプレイの回転と一致するように設定されます。このデフォルトのケースでは、CameraX は、ユーザーが期待する画像をアプリのプレビューで簡単に作成できるように出力を生成します。回転をカスタム値に変更して、マルチディスプレイ デバイスに対応させることも可能です。それには、ユースケース オブジェクトの設定時に、またはユースケース オブジェクトの作成後に動的に、現在のディスプレイの向きを渡します。
アプリで設定ビルダーを使用して、ターゲットの回転を設定できます。また、ライフサイクルの状態が実行中のときでも、アプリはユースケース API のメソッド(ImageAnalysis.setTargetRotation()
など)を使用して回転の設定を更新できます。この方法は、アプリがポートレート モードにロックされている(そのため、回転時に再構成が行われない)場合に使用できます。ただし、写真または解析ユースケースがデバイスの現在の回転を認識できる必要があります。たとえば、顔の向きを正しく検出する、あるいは写真を横向きまたは縦向きに設定するには、回転の認識が必要になることがあります。
キャプチャした画像のデータは回転させずに保存されますが、保存後にギャラリー アプリにおいて画像を正しい向きで表示できるよう、EXIF データに回転の情報が格納されます。
プレビュー データを正しい向きで表示するには、Preview.PreviewOutput()
のメタデータ出力を使用して、GLSurfaceView
の表示用に変換を作成します。
次のコードサンプルは、設定 API を使用して回転を設定する方法を示しています。
Kotlin
val previewConfig = PreviewConfig.Builder() .setTargetRotation(windowManager.defaultDisplay.rotation) .build()
Java
PreviewConfig previewConfig = new PreviewConfig.Builder() .setTargetRotation(getWindowManager().getDefaultDisplay().getRotation()) .build();
各ユースケースは設定された回転に基づいて、画像データを直接回転させるか、回転されていない画像データの回転メタデータをユーザーに提供します。
- Preview:
GLSurfaceView
の表示用に適切な変換を作成するためのメタデータ出力をPreview.PreviewOutput.getRotationDegrees()
で取得できます。 - ImageAnalysis: 表示座標と相対的な画像バッファ座標を認識できるよう、メタデータ出力が提供されます。
analyze()
メソッドは、ビューファインダーと一致するように画像解析データに適用する必要がある回転を表すrotationDegrees
パラメータを提供します。 - ImageCapture: 画像の EXIF メタデータが変更され、回転の設定に注釈が付けられます。
カメラの解像度
デバイスの機能、デバイスがサポートするハードウェア レベル、ユースケース、規定されているアスペクト比の組み合わせに基づいて画像解像度を CameraX で設定できます。また、対象の構成をサポートするユースケースでは、対応するアスペクト比を使用して特定のターゲット解像度を設定することができます。ターゲット アスペクト比に合致する解像度は、特定のターゲット解像度より優先されます。
自動解像度
CameraX では、CameraX.bindToLifecycle()
で指定されたユースケースに基づいて、最適な解像度設定を自動的に決定できます。可能であれば、1 つのセッションで同時実行する必要があるすべてのユースケースを CameraX.bindToLifecycle()
の 1 回の呼び出しで指定します。CameraX は、デバイスがサポートするハードウェア レベルや、デバイスの特徴(デバイスが使用可能なストリーム設定の限度を超えている、あるいはその設定に対応していないことがある)を考慮して、バインドされているユースケースのセットに基づいて解像度を決定します。この目的は、デバイスに固有のコードパスを最小限に抑えつつ、アプリをさまざまなデバイスで実行できるようにすることです。
画像キャプチャおよび画像解析ユースケースのデフォルトのアスペクト比は 4:3 です。
UI の設計に基づいてアプリで目的のアスペクト比を指定できるようにするために、ユースケースでアスペクト比を設定できるようになっています。CameraX の出力は、リクエストされたアスペクト比とデバイスがサポートするアスペクト比ができる限り一致するように生成されます。完全に一致する解像度がサポートされていない場合、条件に最も近い解像度が選択されます。つまり、アプリは、アプリ内におけるカメラのアスペクト比を決定し、CameraX は、各デバイスでそのアスペクト比に適合する最適なカメラ解像度の設定を決定します。
たとえば、アプリは次のいずれかを行います。
- 画像キャプチャで 4:3 を使用するようにレイアウトを設定します。
- 全画面レイアウトを指定します。画面の解像度の違いやシステムの UI バーを考慮すると、アスペクト比はデバイスごとに異なります。
- 正方形のレイアウトを指定します。
CameraX は内部の Camera2 サーフェス解像度を自動的に選択します。次の表にその解像度を示します。
ユースケース | 内部のサーフェス解像度 | 出力データの解像度 |
---|---|---|
プレビュー | アスペクト比: 設定目標に最も適合する解像度。 | 内部のサーフェス解像度。ターゲット アスペクト比に合わせてビューが切り抜き、サイズ変更、回転を行えるようにメタデータが提供されます。 |
デフォルトの解像度: プレビューの最大解像度、または上記のアスペクト比に適合するデバイス推奨の最大解像度。 | ||
最大解像度: プレビュー サイズ(デバイスの画面解像度に最適なサイズ、または 1080p(1920x1080)のどちらか小さいほう)。 | ||
画像解析 | アスペクト比: 設定目標に最も適合する解像度。 | 内部のサーフェス解像度。 |
デフォルトの解像度: ターゲット解像度のデフォルト設定は 640x480 です。ターゲット解像度と対応するアスペクト比の両方を調整することで、1080p 未満の最適な解像度に設定されます。 | ||
最大解像度: CameraX によって 1080p に制限されています。デフォルトではターゲット解像度が 640x480 に設定されるため、解像度を 640x480 より大きくしたい場合は、setTargetResolution と setTargetAspectRatio を使用して、サポートされている解像度の中から最も近いものを取得する必要があります。 | ||
画像キャプチャ | アスペクト比: 設定に最も適合するアスペクト比。 | 内部のサーフェス解像度。 |
デフォルトの解像度: 使用可能な最大解像度、または上記のアスペクト比に適合するデバイス推奨の最大解像度。 | ||
最大解像度: StreamConfigurationMap#getOutputSizes から取得される、JPEG 形式のカメラデバイスの最大出力解像度。 |
解像度を指定する
次のコードサンプルに示すように、setTargetResolution(Size resolution)
メソッドを使用してユースケースの設定を作成する場合、具体的な解像度を設定できます。
Kotlin
val imageAnalysisConfig = ImageAnalysisConfig.Builder() .setTargetResolution(Size(1280, 720)) .build()
Java
ImageAnalysisConfig config = new ImageAnalysisConfig.Builder() .setTargetResolution(new Size(1280, 720)) .build();
指定した解像度に基づいて、具体的なターゲット アスペクト比を設定できます。ターゲット アスペクト比は、解像度の選択に影響を及ぼします。ターゲット解像度に適合するようにターゲット アスペクト比を設定すると、解像度が選択されます。解像度の選択では、デバイスの機能や他にアタッチされているユースケースが考慮されます。
リクエストとまったく同じ解像度とアスペクト比を設定できない場合は、リクエストより大きい解像度で最も近いものが選択されます。選択できる解像度がない場合は、640x480 に戻されます。
CameraX はリクエストに基づいて最適な解像度を適用します。アスペクト比を満たすことが最も重要な場合は、setTargetAspectRatio
のみを指定します。これにより、CameraX がデバイスに最適な解像度を決定します。画像処理の効率を高めるために解像度を指定することがアプリで最も重要な場合(たとえば、デバイスの処理能力に基づいて小または中サイズの画像を選択する場合)は、setTargetResolution(Size resolution)
を使用します。
アプリで正確な解像度が必要な場合は、createCaptureSession
の表を参照して、各ハードウェア レベルでサポートされている最大解像度を確認してください。現在のデバイスでサポートされている特定の解像度を確認するには、StreamConfigurationMap.getOutputSize(int)
を参照してください。
アプリが Android 10 で実行されている場合は、isSessionConfigurationSupported
を使用して特定の SessionConfiguration
を確認できます。
フォーカスの制御
CameraControl
API は、「タップしてフォーカス」機能を提供します。CameraControl
を取得する際は、レンズの向きを指定します。
Kotlin
CameraX.getCameraControl(LensFacing lensFacing)
Java
CameraX.getCameraControl(LensFacing lensFacing);
タップしてフォーカスを実行するには、MeteringPointFactory
、MeteringPoint
、MeteringMode
、FocusMeteringAction
を使用します。
Kotlin
val factory = SensorOrientedMeteringPointFactory(width, height) val point = factory.createPoint(x, y) val action = FocusMeteringAction.Builder.from(point, FocusMeteringAction.MeteringMode.AF_ONLY) .addPoint(point2, FocusMeteringAction.MeteringMode.AE_ONLY) // could have many .setAutoFocusCallback { } // auto calling cancelFocusAndMetering in 5 seconds .setAutoCancelDuration(5, TimeUnit.SECONDS) .build()
Java
MeteringPointFactory factory = new SensorOrientedMeteringPointFactory(width, height); MeteringPoint point = factory.createPoint(x, y); FocusMeteringAction action = FocusMeteringAction.Builder.from(point, MeteringMode.AF_ONLY) .addPoint(point2, MeteringMode.AE_ONLY) // could have many .setAutoFocusCallback(new OnAutoFocusListener(){ public void onFocusCompleted(boolean isSuccess) { } }) // auto calling cancelFocusAndMetering in 5 seconds .setAutoCancelDuration(5, TimeUnit.SECONDS) .build();
参考情報
CameraX について詳しくは、以下の参考情報をご確認ください。
コードラボ
コードサンプル