Camera2 Extensions API

توجه: این صفحه به بسته Camera2 اشاره دارد. توصیه می‌کنیم از CameraX استفاده کنید، مگراینکه برنامه‌تان به ویژگی‌های خاص و سطح پایین Camera2 نیاز داشته باشد. ‫CameraX و Camera2 هر دو از Android 5.0 (سطح میانای برنامه‌سازی کاربردی ۲۱) و بالاتر پشتیبانی می‌کنند.

Camera2 یک Extensions API برای دسترسی به افزونه‌هایی ارائه می‌دهد که سازندگان دستگاه در دستگاه‌های Android مختلف پیاده‌سازی کرده‌اند. برای مشاهده فهرست حالت‌های افزونه پشتیبانی‌شده، به افزونه‌های دوربین مراجعه کنید.

برای مشاهده فهرست دستگاه‌هایی که از افزونه‌ها پشتیبانی می‌کنند، به دستگاه‌های پشتیبانی‌شده مراجعه کنید.

معماری افزونه‌ها

تصویر زیر معماری افزونه‌های دوربین را نشان می‌دهد.

شکل ۱. معماری «افزونه‌های دوربین»

برنامه Camera2 می‌تواند ازطریق Camera2 API از افزونه‌ها استفاده کند. Camera2 API روش‌هایی برای پرسمان افزونه‌های دردسترس، پیکربندی جلسه دوربین افزونه، و برقراری ارتباط با کتابخانه OEM «افزونه‌های دوربین» ارائه می‌دهد. این به برنامه شما اجازه می‌دهد از افزونه‌هایی مثل «حالت شب»، HDR، «خودکار»، «بوکه»، یا «رتوش چهره» استفاده کند.

آزمایش کردن دستگاه دوربین برای سازگاری با Camera2 Extensions API

تکه‌کد زیر بررسی می‌کند که آیا دستگاه از Camera2 Extensions API پشتیبانی می‌کند یا نه. همه دستگاه‌ها از افزونه‌ها پشتیبانی نمی‌کنند یا ممکن است دستگاه از زیرمجموعه‌ای از افزونه‌ها پشتیبانی کند. قطعه کد فهرستی از شناسه‌های دوربین سازگار را برمی‌گرداند که از افزونه‌های دوربین پشتیبانی می‌کنند.

کاتلین

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 با Camera2 Extensions API

Camera2 Extensions API، وقتی با دستگاه‌های سازگار استفاده شود، به شما امکان می‌دهد به افزونه‌های دوربین خاصی دسترسی پیدا کنید. تکه‌کد زیر نمونه‌ای از نحوه ایجاد 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 را ببینید و برای اطلاعات بیشتر، نمونه‌های عمومی Camera2 Extensions API را مشاهده کنید.