Camera2 Extensions API

注: このページでは、Camera2 パッケージについて言及しています。アプリで Camera2 の特定の低レベル機能が必要な場合を除き、CameraX を使用することをおすすめします。CameraX と Camera2 は、どちらも Android 5.0(API レベル 21)以降に対応しています。

Camera2 には、デバイスのメーカーが各種 Android デバイスに実装した拡張機能にアクセスするための Extensions API が用意されています。サポートされている拡張機能モードの一覧については、カメラの拡張機能についての説明をご覧ください。

拡張機能をサポートするデバイスの一覧については、サポートされているデバイスについての説明をご覧ください。

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

次の図は、カメラの拡張機能のアーキテクチャを示しています。

図 1. カメラの拡張機能のアーキテクチャ

Camera2 アプリは、Camera2 API を通じて拡張機能を使用できます。Camera2 API には、利用可能な拡張機能の照会、拡張機能カメラ セッションの構成、Camera Extensions OEM ライブラリとの通信を行う方法が用意されています。これにより、アプリは夜景、HDR、オート、ボケ、顔写真加工などの拡張機能を使用できます。

Camera2 Extensions API との互換性についてカメラデバイスをテストする

次のコード スニペットは、デバイスが Camera2 Extensions API をサポートしているかどうかを確認します。拡張機能はすべてのデバイスでサポートされているわけではありません。また、デバイスが拡張機能のサブセットをサポートしている場合もあります。このスニペットは、カメラ拡張機能をサポートする互換性のあるカメラ ID のリストを返します。

private fun getExtensionCameraIds(cameraManager: CameraManager): List<String> =
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
        cameraManager.cameraIdList.filter { cameraId ->
            val characteristics = cameraManager.getCameraCharacteristics(cameraId)
            val extensionCharacteristics =
                cameraManager.getCameraExtensionCharacteristics(cameraId)
            val capabilities =
                characteristics.get(CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES)
            extensionCharacteristics.supportedExtensions.isNotEmpty() &&
                capabilities?.contains(
                    CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE
                ) ?: false
        }
    } else emptyList()

Camera2 Extensions API を使用して CameraExtensionSession を作成する

Camera2 Extensions API を対応デバイスで使用すると、特定のカメラ拡張機能にアクセスできます。次のコード スニペットは、既存の Camera2 アプリケーションで夜間撮影モードを使用するために CameraExtensionSession を作成する方法の例を示しています。

private val captureCallbacks = object : CameraExtensionSession.ExtensionCaptureCallback() {
    // Implement Capture Callbacks.
}
private val extensionSessionStateCallback = object : CameraExtensionSession.StateCallback() {
    override fun onConfigured(session: CameraExtensionSession) {
        cameraExtensionSession = session
        try {
            val captureRequest =
                cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW).apply {
                    addTarget(previewSurface)
                }.build()
            session.setRepeatingRequest(
                captureRequest,
                Dispatchers.IO.asExecutor(),
                captureCallbacks
            )
        } catch (e: CameraAccessException) {
            Snackbar.make(
                previewView,
                "Failed to preview capture request",
                Snackbar.LENGTH_SHORT
            ).show()
            requireActivity().finish()
        }
    }

    override fun onClosed(session: CameraExtensionSession) {
        super.onClosed(session)
        cameraDevice.close()
    }

    override fun onConfigureFailed(session: CameraExtensionSession) {
        Snackbar.make(
            previewView,
            "Failed to start camera extension preview",
            Snackbar.LENGTH_SHORT
        ).show()
        requireActivity().finish()
    }
}

private fun startExtensionSession() {
    val outputConfig = arrayListOf(
        OutputConfiguration(stillImageReader.surface),
        OutputConfiguration(previewSurface)
    )
    val extensionConfiguration = ExtensionSessionConfiguration(
        CameraExtensionCharacteristics.EXTENSION_NIGHT,
        outputConfig,
        Dispatchers.IO.asExecutor(),
        extensionSessionStateCallback
    )
    cameraDevice.createExtensionSession(extensionConfiguration)
}

参考情報

詳細については、CameraExtensionCharacteristics をご覧ください。また、公開されている Camera2 Extensions API のサンプルもご覧ください。