Camera2 擴充功能 API

注意:本頁面所述是指 Camera2 套件。除非應用程式需要 Camera2 的特定低階功能,否則建議使用 CameraX。CameraX 和 Camera2 均支援 Android 5.0 (API 級別 21) 以上版本。

Camera2 提供擴充功能 API,可用於存取裝置製造商在不同 Android 裝置上實作的擴充功能。如需支援的擴充功能模式清單,請參閱「相機擴充功能」。

如需支援擴充功能的裝置清單,請參閱「支援的裝置」。

擴充功能架構

下圖顯示相機擴充功能的架構。

圖 1 相機擴充功能架構

Camera2 應用程式可透過 Camera2 API 使用擴充功能。相機 2 API 可讓您查詢可用的擴充功能、設定擴充功能 ,並與 Camera Extensions OEM 程式庫通訊。這個 可讓應用程式使用「夜晚」、「高動態範圍」、「自動」、「散景」或 修容功能

測試相機裝置是否符合 Camera2 Extensions API 相容性

下列程式碼片段會檢查裝置是否支援 Camera2 擴充功能 API。並非所有裝置或裝置都支援部分擴充功能 。程式碼片段會傳回支援相容相機 ID 的清單 相機擴充功能

KotlinJava

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

使用 Camera2 Extensions API 建立 CameraExtensionSession

與相容裝置搭配使用 Camera2 Extensions API 時,你可以 特定相機擴充功能以下程式碼片段為 如何建立 CameraExtensionSession ,在現有 Camera2 應用程式中使用夜間拍攝模式。

KotlinJava

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 範例 瞭解詳情。