ベンダー拡張

CameraX には、スマートフォン メーカーが特定のスマートフォン用に実装した効果(ピンぼけ、HDR など)を使用するための API が用意されています。デバイスでベンダー拡張機能をサポートするには、次の条件をすべて満たしている必要があります。

  • デバイスの OEM から、この効果に対するライブラリ サポートが提供されている。
  • OEM ライブラリが現在のデバイスにインストールされている。
  • OEM ライブラリから、デバイスが拡張機能をサポートしていると報告される。
  • デバイスに、ライブラリに必要なバージョンのオペレーティング システムがインストールされている。

拡張機能を選択的に有効にできます。拡張機能がデバイスでサポートされており、かつ物理的に利用できる場合は有効になります。該当しない場合は、グレースフル デグラデーションが行われます。

ベンダーはすべての効果および機能の実装を提供する必要はありません。ベンダー提供の実装がない機能の場合、デフォルトで CameraX の実装が適用されます。デフォルトの実装では機能を利用できないことが報告され、その有効化がスキップされます。

拡張機能のアーキテクチャ

次の図は、CameraX を使用した拡張機能のアーキテクチャを示しています。

図 1. 拡張機能の CameraX アーキテクチャ

拡張機能は CameraX の Camera2 コアとは別のものです。図の赤い矢印は、ユーザーが拡張機能ベースの機能(HDR 画像キャプチャなど)をトリガーしたときのメインとなるデータフローを示しています。

画像キャプチャとプレビューの効果を有効にする

拡張機能 API を使用する前に、ExtensionsManager#getInstance(Context) メソッドを使用して ExtensionsManager インスタンスを取得します。これにより、拡張機能の可用性情報をクエリできます。次に、拡張機能が有効になっている CameraSelector を取得します。CameraSelector 拡張機能を有効にして bindToLifecycle() メソッドを呼び出すとき、画像キャプチャとプレビューのユースケースに拡張機能モードが適用されます。

画像キャプチャとプレビューのユースケースの拡張機能を実装するには、次のコードサンプルをご覧ください。

Kotlin

import androidx.camera.extensions.ExtensionMode
import androidx.camera.extensions.ExtensionsManager

fun onCreate() {
    // Create a camera provider
    val cameraProvider : ProcessCameraProvider = ... // Get the provider instance

    lifecycleScope.launch {
        // Create an extensions manager
        val extensionsManager = ExtensionsManager.getInstance(lifecycleOwner).await()

        // Select the camera
        val cameraSelector = CameraSelector.DEFAULT_BACK_CAMERA

        // Query if extension is available.
        if (extensionsManager.isExtensionAvailable(
                cameraProvider,
                cameraSelector,
                ExtensionMode.BOKEH
            )
        ) {
            // Unbind all use cases before enabling different extension modes.
            cameraProvider.unbindAll()

            // Retrieve extension enabled camera selector
            val bokehCameraSelector = extensionsManager.getExtensionEnabledCameraSelector(
                cameraProvider,
                cameraSelector,
                ExtensionMode.BOKEH
            )

            // Bind image capture and preview use cases with the extension enabled camera selector.
            val imageCapture = ImageCapture.Builder().build()
            val preview = Preview.Builder().build()
            cameraProvider.bindToLifecycle(
                lifecycleOwner,
                bokehCameraSelector,
                imageCapture,
                preview
            )
        }
    }
}

Java

import androidx.camera.extensions.ExtensionMode;
import androidx.camera.extensions.ExtensionsManager;

void onCreate() {
    // Create a camera provider
    ProcessCameraProvider cameraProvider = ... // Get the provider instance

    // Call the getInstance function to retrieve a ListenableFuture object
    ListenableFuture future = ExtensionsManager.getInstance(lifecycleOwner);

    // Obtain the ExtensionsManager instance from the returned ListenableFuture object
    future.addListener(() -> {
        try {
            ExtensionsManager extensionsManager = future.get();

            // Select the camera
            CameraSelector cameraSelector = CameraSelector.DEFAULT_BACK_CAMERA;

            // Query if extension is available.
            if (extensionsManager
                .isExtensionAvailable(cameraProvider, cameraSelector, ExtensionMode.BOKEH)) {
                // Unbind all use cases before enabling different extension modes.
                cameraProvider.unbindAll();

                // Retrieve extension enabled camera selector
                CameraSelector bokehCameraSelector = extensionsManager
                    .getExtensionEnabledCameraSelector(cameraProvider, cameraSelector, ExtensionMode.BOKEH);

                // Bind image capture and preview use cases with the extension enabled camera selector.
                ImageCapture imageCapture = new ImageCapture.Builder().build();
                Preview preview = new Preview.Builder().build();
                cameraProvider.bindToLifecycle(lifecycleOwner, bokehCameraSelector, imageCapture, preview);
            }
        } catch (ExecutionException | InterruptedException e) {
            // This should not happen unless the future is cancelled or the thread is interrupted by
            // applications.
        }
    }, ContextCompact.getMainExecutor(context));
}

効果を無効にする

ベンダー拡張機能を無効にするには、すべてのユースケースをアンバインドし、画像キャプチャとプレビューのユースケースを通常のカメラセレクタで再バインドします。たとえば、CameraSelector.DEFAULT_BACK_CAMERA を使用して背面カメラに再バインドします。

参考情報

CameraX について詳しくは、以下の参考情報をご確認ください。

Codelab

  • CameraX のスタートガイド
  • コードサンプル

  • CameraX の公式サンプルアプリ
  • レガシー API の削除履歴

    拡張機能 API の新しいセットが 1.0.0-alpha26 で公開されました。デベロッパーは、拡張機能に対応したカメラセレクタを取得するだけで、ユースケースをバインドする際に使用できます。以下のレガシー エクステンダー クラスと関連 API は、camera-extensions 1.0.0-alpha26 で非推奨となり、1.0.0-alpha28 で削除されました。

    • AutoImageCaptureExtender
    • AutoPreviewExtender
    • BeautyImageCaptureExtender
    • BeautyPreviewExtender
    • BokehImageCaptureExtender
    • BokehPreviewExtender
    • HdrImageCaptureExtender
    • HdrPreviewExtender
    • NightImageCaptureExtender
    • NightPreviewExtender