API расширений Camera2

Примечание. Эта страница относится к пакету Camera2 . Если вашему приложению не требуются специальные низкоуровневые функции Camera2, мы рекомендуем использовать CameraX . И CameraX, и Camera2 поддерживают Android 5.0 (уровень API 21) и выше.

Camera2 предоставляет API расширений для доступа к расширениям , которые производители устройств реализовали на различных устройствах Android. Список поддерживаемых режимов расширений см. в разделе Расширения камеры .

Список устройств, поддерживающих расширения, см. в разделе Поддерживаемые устройства .

Архитектура расширений

На следующем изображении показана архитектура расширений камеры.

Рисунок 1. Архитектура расширений камер

Приложение Camera2 может использовать расширения через API Camera2. API Camera2 предоставляет способы запроса доступных расширений, настройки сеанса дополнительной камеры и взаимодействия с OEM-библиотекой расширений камеры. Это позволяет вашему приложению использовать такие расширения, как «Ночь», «HDR», «Авто», «Боке» или «Ретушь лица».

Проверьте устройство камеры на совместимость API расширений Camera2.

Следующий фрагмент кода проверяет, поддерживает ли устройство API расширений Camera2. Расширения поддерживаются не всеми устройствами, либо устройство может поддерживать часть расширений. Фрагмент возвращает список совместимых идентификаторов камер, которые поддерживают расширения камер.

Котлин


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()

Ява


private List<String> getExtensionCameraIds(CameraManager cameraManager)
        throws CameraAccessException {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
        return Arrays.stream(cameraManager.getCameraIdList()).filter(cameraId -> {
            try {
                CameraCharacteristics characteristics =
                        cameraManager.getCameraCharacteristics(cameraId);
                CameraExtensionCharacteristics extensionCharacteristics =
                        cameraManager.getCameraExtensionCharacteristics(cameraId);
                IntStream capabilities =
                    Arrays.stream(
                                characteristics.get(
                                        CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES
                                )
                        );
                return !extensionCharacteristics.getSupportedExtensions().isEmpty() &&
                       capabilities.anyMatch(capability -> capability == CameraCharacteristics
                                        .REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE
                        );
            } catch (CameraAccessException e) {
                throw new RuntimeException(e);
            }
        }).collect(Collectors.toList());
    } else {
        return Collections.emptyList();
    }
}

Создайте сеанс CameraExtensionSession с помощью API расширений Camera2.

API расширений Camera2 при использовании с совместимыми устройствами позволяет получить доступ к определенным расширениям камеры. В следующем фрагменте кода показан пример создания CameraExtensionSession для использования режима ночной съемки для существующего приложения Camera2.

Котлин


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)
}

Ява


private CameraExtensionSession.ExtensionCaptureCallback captureCallbacks =
        new CameraExtensionSession.ExtensionCaptureCallback() {
            // Implement Capture Callbacks
        };

private CameraExtensionSession.StateCallback extensionSessionStateCallback =
        new CameraExtensionSession.StateCallback() {
            @Override
            public void onConfigured(@NonNull CameraExtensionSession session) {
                cameraExtensionSession = session;
                try {
                    CaptureRequest.Builder captureRequestBuilder =
                            cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
                    captureRequestBuilder.addTarget(previewSurface);
                    CaptureRequest captureRequest = captureRequestBuilder.build();
                    session.setRepeatingRequest(captureRequest, backgroundExecutor, captureCallbacks);
                } catch (CameraAccessException e) {
                    Snackbar.make(
                            previewView,
                            "Failed to preview capture request",
                            Snackbar.LENGTH_SHORT
                    ).show();
                    requireActivity().finish();
                }
            }

            @Override
            public void onClosed(@NonNull CameraExtensionSession session) {
                super.onClosed(session);
                cameraDevice.close();
            }

            @Override
            public void onConfigureFailed(@NonNull CameraExtensionSession session) {
                Snackbar.make(
                        previewView,
                        "Failed to start camera extension preview",
                        Snackbar.LENGTH_SHORT
                ).show();
                requireActivity().finish();
            }
        };

private void startExtensionSession() {
    ArrayList<OutputConfiguration> outputConfig = new ArrayList<>();
    outputConfig.add(new OutputConfiguration(stillImageReader.getSurface()));
    outputConfig.add(new OutputConfiguration(previewSurface));
    ExtensionSessionConfiguration extensionConfiguration = new ExtensionSessionConfiguration(
            CameraExtensionCharacteristics.EXTENSION_NIGHT,
            outputConfig,
            backgroundExecutor,
            extensionSessionStateCallback
    );
}

Дополнительные ресурсы

Дополнительные сведения см. в разделе CameraExtensionCharacteristics и в общедоступных примерах API расширений Camera2 .