Uwaga: ta strona dotyczy pakietu Camera2. Jeśli Twoja aplikacja nie wymaga określonych funkcji niskiego poziomu z Camera2, zalecamy używanie CameraX. Zarówno CameraX, jak i Camera2 obsługują Androida 5.0 (poziom interfejsu API 21) i nowsze wersje.
Camera2 udostępnia interfejs Extensions API, który umożliwia dostęp do rozszerzeń zaimplementowanych przez producentów na różnych urządzeniach z Androidem. Listę obsługiwanych trybów rozszerzeń znajdziesz w artykule Rozszerzenia aparatu.
Listę urządzeń obsługujących rozszerzenia znajdziesz w artykule Obsługiwane urządzenia.
Architektura rozszerzeń
Poniższy obraz przedstawia architekturę rozszerzeń aparatu.
Aplikacja Camera2 może używać rozszerzeń za pomocą interfejsu Camera2 API. Interfejs Camera2 API umożliwia wysyłanie zapytań o dostępne rozszerzenia, konfigurowanie sesji aparatu z rozszerzeniami i komunikowanie się z biblioteką OEM rozszerzeń aparatu. Dzięki temu aplikacja może korzystać z rozszerzeń takich jak tryb nocny, HDR, tryb automatyczny, efekt bokeh czy retusz twarzy.
Testowanie zgodności aparatu z interfejsem Camera2 Extensions API
Ten fragment kodu sprawdza, czy urządzenie obsługuje interfejs Camera2 Extensions API. Rozszerzenia nie są obsługiwane przez wszystkie urządzenia lub urządzenie może obsługiwać tylko niektóre rozszerzenia. Fragment kodu zwraca listę identyfikatorów zgodnych aparatów, które obsługują rozszerzenia aparatu.
Kotlin
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()
Java
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(); } }
Tworzenie sesji CameraExtensionSession za pomocą interfejsu Camera2 Extensions API
Interfejs Camera2 Extensions API, gdy jest używany ze zgodnymi urządzeniami, umożliwia dostęp do niektórych rozszerzeń aparatu. Poniższy fragment kodu pokazuje, jak utworzyć CameraExtensionSession, aby używać trybu nocnego w istniejącej aplikacji Camera2.
Kotlin
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) }
Java
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 ); }
Dodatkowe materiały
Więcej informacji znajdziesz w CameraExtensionCharacteristics. Możesz też zapoznać się z publicznymi przykładami interfejsu Camera2 Extensions API.