圖片擷取

圖片拍攝功能的用途為拍出高解析度的優質相片,除了簡單的手動相機控制選項,還提供自動白平衡、自動曝光和自動對焦 (3A) 功能。呼叫端負責決定所攝相片的使用方式,包括下列選項:

ImageCapture 運作時採用的可自訂執行工具分成兩種類型:回呼執行工具和 IO 執行工具。

  • 回呼執行工具是 takePicture 方法的參數,用於執行使用者提供的 OnImageCapturedCallback()
  • 如果呼叫端選擇將圖片儲存至特定檔案位置,您可以指定 IO 執行工具。如要設定這類工具,請呼叫 ImageCapture.Builder.setIoExecutor(Executor)。如未提供執行工具,CameraX 將預設使用內部 IO 執行工具完成工作。

設定圖片拍攝功能

圖片拍攝功能提供基本的拍照控制選項,例如閃光燈、連續自動對焦、零延遲快門等。

setCaptureMode()

使用 ImageCapture.Builder.setCaptureMode() 設定拍照時的拍攝模式:

拍攝模式預設為 CAPTURE_MODE_MINIMIZE_LATENCY。詳情請見 setCaptureMode() 參考說明文件。

零延遲快門

自 1.2 版起,零延遲快門 (CAPTURE_MODE_ZERO_SHOT_LAG) 已可做為拍攝模式。相較於預設拍攝模式 CAPTURE_MODE_MINIMIZE_LATENCY,啟用零延遲快門可大幅縮短延遲時間,因此能夠準確捕捉所有精彩時刻。

零延遲快門會使用環形緩衝區,儲存最近三個拍攝畫面。當使用者按下拍攝按鈕時,CameraX 會叫用 takePicture(),而環形緩衝區則會擷取時間戳記最接近按下按鈕時間的拍攝畫面。接著,CameraX 會重新處理拍攝工作階段,從該畫面產生圖片,並以 JPEG 格式儲存到磁碟。

必要條件

啟用零延遲快門前,請先使用 isZslSupported() 判斷裝置是否符合以下需求:

如果裝置不符合最低需求,CameraX 會改回採用 CAPTURE_MODE_MINIMIZE_LATENCY

零延遲快門僅適用於圖片拍攝用途。您無法針對錄影用途或搭配相機擴充功能,啟用這類快門。最後,由於使用閃光燈會導致延遲時間拉長,因此如果閃光燈已開啟或處於自動模式,零快門延遲就無法運作。如要進一步瞭解如何設定閃光燈模式,請參閱 setFlashMode()

啟用零延遲快門

如要啟用零延遲快門,請將 CAPTURE_MODE_ZERO_SHOT_LAG 傳遞至 ImageCapture.Builder.setCaptureMode()。若無法成功傳遞,setCaptureMode() 會改回使用 CAPTURE_MODE_MINIMIZE_LATENCY

setFlashMode()

預設的閃光燈模式為 FLASH_MODE_OFF。如要設定閃光燈模式,請使用 ImageCapture.Builder.setFlashMode()

拍照

以下程式碼範例說明如何設定應用程式的拍照功能:

Kotlin

val imageCapture = ImageCapture.Builder()
    .setTargetRotation(view.display.rotation)
    .build()

cameraProvider.bindToLifecycle(lifecycleOwner, cameraSelector, imageCapture,
    imageAnalysis, preview)

Java

ImageCapture imageCapture =
    new ImageCapture.Builder()
        .setTargetRotation(view.getDisplay().getRotation())
        .build();

cameraProvider.bindToLifecycle(lifecycleOwner, cameraSelector, imageCapture, imageAnalysis, preview);

請注意,bindToLifecycle() 會傳回 Camera 物件。如需進一步瞭解如何控制相機輸出內容 (例如縮放和曝光),請參閱這份指南

相機設定完成後,下列程式碼就能根據使用者動作拍照:

Kotlin

fun onClick() {
    val outputFileOptions = ImageCapture.OutputFileOptions.Builder(File(...)).build()
    imageCapture.takePicture(outputFileOptions, cameraExecutor,
        object : ImageCapture.OnImageSavedCallback {
            override fun onError(error: ImageCaptureException)
            {
                // insert your code here.
            }
            override fun onImageSaved(outputFileResults: ImageCapture.OutputFileResults) {
                // insert your code here.
            }
        })
}

Java

public void onClick() {
    ImageCapture.OutputFileOptions outputFileOptions =
            new ImageCapture.OutputFileOptions.Builder(new File(...)).build();
    imageCapture.takePicture(outputFileOptions, cameraExecutor,
        new ImageCapture.OnImageSavedCallback() {
            @Override
            public void onImageSaved(ImageCapture.OutputFileResults outputFileResults) {
                // insert your code here.
            }
            @Override
            public void onError(ImageCaptureException error) {
                // insert your code here.
            }
       }
    );
}

圖片拍攝方法完整支援 JPEG 格式。如需瞭解如何將 YUV_420_888 格式的 Media.Image 物件轉換為 RGB Bitmap 物件,請參閱 YuvToRgbConverter.kt 的程式碼範例。

其他資源

如要進一步瞭解 CameraX,請參閱下列其他資源。

程式碼研究室

  • 開始使用 CameraX
  • 程式碼範例

  • CameraX 範例應用程式