相機擴充功能

裝置製造商可公開散景、夜間模式和 HDR 等擴充功能 透過由 Google Cloud 提供的 Camera Extensions 介面 原始設備製造商 (OEM) 供應商程式庫開發人員可以使用 Camera2 Extensions APICameraX Extensions API ,存取原始設備製造商 (OEM) 供應商程式庫中實作的擴充功能。

如要查看支援的擴充功能清單,這份清單在 Camera2 中均相同 和 CameraX,請參閱 CameraX Extensions API。 新增擴充功能的方法: 回報 Issue Tracker

本頁面說明如何在以下項目中實作及啟用 OEM 供應商程式庫 裝置。

建築

下圖說明相機擴充功能的架構 介面或 extensions-interface建築

圖 1. Camera Extensions 架構圖

如圖所示,如要支援 Camera Extensions,您必須 導入原始設備製造商 (OEM) 供應商程式庫提供的 extensions-interface。您的 原始設備製造商 (OEM) 供應商程式庫啟用兩個 API: CameraX Extensions APICamera2 Extensions API, 分別由 CameraX 和 Camera2 應用程式使用的資料存取 供應商擴充功能。

導入原始設備製造商 (OEM) 供應商程式庫

如要導入 OEM 供應商程式庫,請複製 camera-extensions-stub敬上 複製到系統程式庫專案中這些檔案會定義 Camera Extensions 存取 API

camera-extensions-stub 檔案分為以下類別:

重要介面檔案 (請勿修改)

  • PreviewExtenderImpl.java
  • ImageCaptureExtenderImpl.java
  • ExtenderStateListener.java
  • ProcessorImpl.java
  • PreviewImageProcessorImpl.java
  • CaptureProcessorImpl.java
  • CaptureStageImpl.java
  • RequestUpdateProcessorImpl.java
  • ProcessResultImpl.java
  • advanced/AdvancedExtenderImpl.java
  • advanced/Camera2OutputConfigImpl.java
  • advanced/Camera2SessionConfigImpl.java
  • advanced/ImageProcessorImpl.java
  • advanced/ImageReaderOutputConfigImpl.java
  • advanced/ImageReferenceImpl.java
  • advanced/MultiResolutionImageReaderOutputConfigImpl.java
  • advanced/OutputSurfaceImpl.java
  • advanced/RequestProcessorImpl.java
  • advanced/SessionProcessorImpl.java
  • advanced/SurfaceOutputConfigImpl.java

必要導入做法 (新增導入方式)

  • ExtensionVersionImpl.java
  • InitializerImpl.java

Bokeh 擴充工具類別 (如果支援 Bokeh 擴充功能,即可實作)

  • BokehImageCaptureExtenderImpl.java
  • BokehPreviewExtenderImpl.java
  • advanced/BokehAdvancedExtenderImpl.java

夜間擴充器類別 (如果支援夜間擴充功能,則實作此類別)

  • NightImageCaptureExtenderImpl.java
  • NightPreviewExtenderImpl.java
  • advanced/NightAdvancedExtenderImpl.java

自動擴展器類別 (在支援自動擴充功能時導入)

  • AutoImageCaptureExtenderImpl.java
  • AutoPreviewExtenderImpl.java
  • advanced/AutoAdvancedExtenderImpl.java

HDR 擴充器類別 (在支援 HDR 擴充功能時實作)

  • HdrImageCaptureExtenderImpl.java
  • HdrPreviewExtenderImpl.java
  • advanced/HdrAdvancedExtenderImpl.java

修容擴充功能類別 (如果支援 Face Retouch 擴充功能,即可實作)

  • BeautyImageCaptureExtenderImpl.java
  • BeautyPreviewExtenderImpl.java
  • advanced/BeautyAdvancedExtenderImpl.java

公用程式 (選用,可刪除)

  • advanced/Camera2OutputConfigImplBuilder.java
  • advanced/Camera2SessionConfigImplBuilder.java

您不必為每個擴充功能提供導入方式。如果發生以下情況: 不實作擴充功能,請將 isExtensionAvailable() 設為傳回 false 或 移除對應的擴充器類別Camera2 和 CameraX 擴充功能 API 會向無法使用擴充功能的應用程式回報相關資訊。

我們會逐步說明 Camera2 和 CameraX Extensions API 如何與 供應商庫,以便啟用擴充功能。下圖說明 使用 Night 擴充功能做為範例:

主流

圖 2. 夜間擴充功能導入

  1. 版本驗證:

    Camera2/X 會呼叫 ExtensionVersionImpl.checkApiVersion(),確保 原始設備製造商 (OEM) 導入的 extensions-interface 版本與 Camera2/X 相容 支援的版本。

  2. 供應商程式庫初始化:

    InitializerImpl 具有初始化供應商程式庫的方法 init() 方法。 Camera2/X 會先完成初始化,接著再存取延伸器類別。

  3. 對延伸器類別執行個體化:

    針對擴充功能的延伸類別類別例項化。我們有兩種延長器 類型:基本延伸器和進階擴展器。您必須導入 所有擴充功能的擴充類型。若需更多資訊,請參閲 基本延伸器與進階擴展器

    Camera2/X 會將例項化,並與擴充器類別互動,以便擷取 資訊並啟用擴充功能針對特定擴充功能,Camera2/X 可以 多次例項化延伸器類別。因此,請避免 在建構函式或 init() 呼叫中大幅移植初始化作業。執行 只有當攝影機工作階段即將接近時,才加重。 ,例如在基本擴充程式中呼叫 onInit() 時 已在進階擴展器中呼叫 initSession()

    如果是 Night 擴充功能,下列延伸類別類別會針對 基本擴展器類型

    • NightImageCaptureExtenderImpl.java
    • NightPreviewExtenderImpl.java

    進階擴展器類型則:

    • NightAdvancedExtenderImpl.java
  4. 查看擴充功能是否可用:

    啟用擴充功能之前,isExtensionAvailable() 會檢查 指定相機 ID 可透過延伸器存取 執行個體。

  5. 使用相機資訊將延伸器初始化:

    Camera2/X 會在延伸器例項上呼叫 init(),並將相機傳遞給其相機 ID 和 CameraCharacteristics

  6. 查詢資訊:

    叫用 Extendeder 類別以擷取支援的資訊,例如 仍會擷取預估延遲時間,並從 準備啟用擴充功能。

  7. 在延伸器上啟用擴充功能:

    擴充器類別提供啟用 類別提供將原始設備製造商 (OEM) 掛鉤的機制 導入 Camera2 管道,例如插入擷取要求 或啟用後置處理器

    對於進階延伸器類型,Camera2/X 會與 SessionProcessorImpl:啟用擴充功能。Camera2/X 會擷取 對 SessionProcessorImpl 執行個體呼叫 createSessionProcessor() 延伸器。

以下各節將詳細說明擴充功能流程。

版本驗證

在執行階段從裝置載入原始設備製造商 (OEM) 供應商程式庫時,Camera2/X 檢查程式庫是否與 extensions-interface 版本相容。 extensions-interface 使用語意版本管理 MAJOR.MINOR.PATCH,例如 1.1.0 或 1.2.0。不過,只有 驗證版本時會使用主要版本和次要版本。

確認 Camera2/X 呼叫以確認版本 支援的 ExtensionVersionImpl.checkApiVersion() extensions-interface 版。Camera2/X 會使用 用於判斷是否能啟用擴充功能以及哪些功能 應叫用

主要版本相容性

如果 extension-interface 的主要版本不同, Camera2/X 和廠商庫則視為不相容, 該擴充功能已停用。

回溯相容性

只要主要版本相同,Camera2/X 就會確保 與先前建構的 OEM 供應商程式庫回溯相容 extensions-interface 個版本。舉例來說,如果 Camera2/X 支援 extensions-interface 1.3.0,即實作 1.0.0、 1.1.0 和 1.2.0 仍相容。也就是說 廠商庫的特定版本,Camera2/X 會確保程式庫 與即將推出的 extension-interface 版本回溯相容。

前瞻相容性

前瞻相容性與新版 extensions-interface 的供應商程式庫相容 必須視你 (原始設備製造商) 而定如果您需要使用某些功能實作擴充功能 您可能會想從特定版本開始啟用擴充功能。在本 就可以傳回支援的 extensions-interface 版本。 Camera2/X 程式庫版本符合需求條件。如果 Camera2/X 版本 ,您可以傳回不相容的版本,例如 99.0.0 至 停用擴充功能

供應商程式庫初始化

驗證原始設備製造商 (OEM) 實作的 extensions-interface 版本之後 Camera2/X 會啟動初始化程序。 InitializerImpl.init() 方法會向原始設備製造商 (OEM) 程式庫發出信號,指出應用程式正在試用 才能使用擴充功能

除了版本檢查之外,Camera2/X 不會對原始設備製造商 (OEM) 程式庫發出其他呼叫 直到原始設備製造商 (OEM) 供應商程式庫呼叫 OnExtensionsInitializedCallback.onSuccess() 為止 通知已初始化完成。

您必須實作 InitializerImpl敬上 自 extensions-interface 1.1.0 起。Camera2/X 會略過程式庫初始化 步驟。extensions-interface

基本延長器與進階擴展器

extensions-interface 實作分為兩種類型:基本延伸器和 進階擴展器。自以下日期起,Google 將支援進階延伸器: extensions-interface 1.2.0.

為處理相機 HAL 或內圖片的擴充功能實作基本延伸功能 使用能夠處理 YUV 串流的後置處理器

針對需要自訂 Camera2 的擴充功能實作進階延伸器 串流設定並視需要傳送擷取要求。

比較方式請參閱下表:

基本延長線 進階擴展器
串流設定 已修正
預覽:PRIVATEYUV_420_888 (如有處理器)
仍擷取:JPEGYUV_420_888 (如有處理器)
可透過原始設備製造商 (OEM) 自訂。
正在傳送拍攝要求 只有 Camera2/X 可以傳送擷取要求。您可以將參數設為 這些要求。如果提供拍攝用的處理器,Camera2/X 就可以傳送多個擷取要求,將所有圖片 傳回至處理方 系統會為您提供 RequestProcessorImpl 執行個體, 執行 camera2 擷取要求,並取得結果和圖片。

Camera2/X 會在 startRepeatingstartCapture 上叫用 SessionProcessorImpl 表示原始設備製造商 (OEM) 開始重複 要求預覽,並分別啟動靜態擷取序列。

相機管道中的掛鉤
  • onPresetSession 提供工作階段參數。
  • CameraCaptureSession 設定完畢後,onEnableSession 會立即傳送單一要求。
  • onDisableSessionCameraCaptureSession 關閉前傳送一項要求。
  • initSession 會初始化並傳回自訂 camera2 用於建立擷取工作階段的工作階段設定。
  • 設定 CameraCaptureSession 後,系統會立即叫用 onCaptureSessionStart
  • onCaptureSessionEnd 會在 CameraCaptureSession 關閉前叫用。
適合 在相機 HAL 或處理的處理器中實作的擴充功能 YUV 映像檔
  • 針對擴充功能採用以 Camera2 為基礎的實作方式。
  • 需要自訂串流設定,例如 RAW 串流。
  • 需要互動式擷取序列。
支援的 API 版本 Camera2 擴充功能:Android 13 以上版本
CameraX 擴充功能:camera-extensions 1.1.0 以上版本
Camera2 擴充功能:Android 12L 以上版本
CameraX 擴充功能:camera-extensions 1.2.0-alpha03 以上版本

應用程式流程

下表列出三種應用程式流程及 對應的 Camera Extensions API 呼叫。雖然 Camera2/X 則提供 這些 API,您必須妥善實作供應商程式庫,才能支援這些 API 流程,我們會在後續章節中詳細說明。

Camera2 擴充功能 CameraX 擴充功能
查詢擴充功能可用性 CameraExtensionCharacteristics .getSupportedExtensions ExtensionsManager. isExtensionAvailable
查詢資訊 CameraExtensionCharacteristics. getExtensionSupportedSizes CameraExtensionCharacteristics. getEstimatedCaptureLatencyRangeMillis CameraExtensionCharacteristics. getAvailableCaptureRequestKeys CameraExtensionCharacteristics. getAvailableCaptureResultKeys ExtensionsManager. getEstimatedCaptureLatencyRange

CameraX 會處理程式庫中的其餘資訊。

在啟用擴充功能的情況下預覽及靜態拍攝 CameraDevice. createExtensionSession

cameraExtensionsSession. setRepeatingRequest

cameraExtensionsSession. capture

val cameraSelector = ExtensionsManager. getExtensionEnabledCameraSelector

bindToLifecycle(lifecycleOwner, cameraSelector, preview, ...)

基本延長線

基本延伸器介面可為相機的幾個地方提供掛鉤 這種模型通常已開放原始碼 可以透過自訂筆記本或管線微調每個擴充功能類型都有對應原始設備製造商 (OEM) 所需的對應擴充工具類別 以便實作。

下表列出原始設備製造商 (OEM) 為每種類別 副檔名:

要實作的擴充類別
夜晚 NightPreviewExtenderImpl.java

NightImageCaptureExtenderImpl.java

高動態範圍 HdrPreviewExtenderImpl.java

HdrImageCaptureExtenderImpl.java

汽車 AutoPreviewExtenderImpl.java

AutoImageCaptureExtenderImpl.java

散景 BokehPreviewExtenderImpl.java

BokehImageCaptureExtenderImpl.java

修容 BeautyPreviewExtenderImpl.java

BeautyImageCaptureExtenderImpl.java

我們使用 PreviewExtenderImplImageCaptureExtenderImpl 做為預留位置 。請使用實際的名稱 要實作的檔案

基本擴展器具備下列功能:

  • 設定 CameraCaptureSession 時插入工作階段參數 ( onPresetSession)。
  • 在擷取工作階段開始和結束事件時通知您,並傳送單一 要求透過傳回的參數 (onEnableSessiononDisableSession)。
  • 插入要求擷取參數 (PreviewExtenderImpl.getCaptureStageImageCaptureExtenderImpl.getCaptureStages)。
  • 新增用於預覽的處理器,但仍能完整擷取處理功能 YUV_420_888 個串流。
,瞭解如何調查及移除這項存取權。

一起來看看 Camera2/X 如何叫用 extensions-interface 來完成這三項工作 。

應用程式流程 1:檢查擴充功能可用性

基本擴充程式 AppFlow1

圖 3. 基本延伸器的應用程式流程 1

在這個流程中,Camera2/X 會直接呼叫 isExtensionAvailable() 方法, PreviewExtenderImplImageCaptureExtenderImpl都不需要撥打電話 init()。兩個延伸類別都必須傳回 true,才能啟用擴充功能。

這通常是應用程式要檢查指定擴充功能的第一步 類型在啟用擴充功能之前可支援。 這是因為部分擴充功能僅支援特定相機 ID。

應用程式流程 2:查詢資訊

基本擴充程式 AppFlow2

圖 4. 基本延伸器的應用程式流程 2

判定擴充功能是否可用後,應用程式應查詢 請提供下列資訊,再啟用擴充功能。

  • 仍擷取延遲時間範圍: ImageCaptureExtenderImpl.getEstimatedCaptureLatencyRange 會傳回範圍 讓應用程式評估是否適合 為目前情境啟用擴充功能。

  • 預覽和擷取介面支援的大小: ImageCaptureExtenderImpl.getSupportedResolutionsPreviewExtenderImpl.getSupportedResolutions 會傳回圖片格式清單 平面格式和大小支援的尺寸。

  • 支援的要求和結果鍵: Camera2/X 會叫用下列方法,擷取支援的拍攝作業 從您的實作要求金鑰和結果鍵:

    • ImageCaptureExtenderImpl.getAvailableCaptureRequestKeys
    • ImageCaptureExtenderImpl.getAvailableCapturetResultKeys

Camera2/X 一律會先對這些擴充器類別呼叫 init(),然後再進行查詢 瞭解詳情

應用程式流程 3:在啟用擴充功能的情況下預覽/仍在擷取 (HAL 實作)

基本擴充程式 AppFlow3

圖 5. 基本延伸器的應用程式流程 3

上圖說明啟用預覽和靜止設定的主要流程 而且不需任何處理器即可擷取。這代表相機 HAL 就會處理擴充功能

在這個流程中,Camera2/X 會先呼叫 init(),再呼叫 onInit,藉此通知您。 相機工作階段即將以指定的擴充功能開始。 您可以在 onInit() 中執行大量初始化初始化作業。

設定 CameraCaptureSession 時,Camera2/X 叫用 onPresetSession 以取得工作階段參數。擷取工作階段在 設定成功,Camera2/X 會叫用 onEnableSession 並傳回 CaptureStageImpl 包含擷取參數的例項。相機 2/X 會立即傳送內含這些擷取參數的單一要求,以通知 HAL。同樣地,在擷取工作階段關閉前,Camera2/X 叫用 onDisableSession,然後傳送含有傳回擷取內容的單一要求 參數。

Camera2/X 觸發的重複要求中包含要求參數 由 PreviewExtenderImpl.getCaptureStage() 傳回。此外, 擷取要求中包含 ImageCaptureExtenderImpl.getCaptureStages()

最後,Camera2/X 會在相機工作階段結束後叫用 onDeInit()。 您可以在「onDeinit()」中釋出資源。

預覽處理器

除了相機 HAL 外,您也可以在處理器中實作擴充功能。

實作 PreviewExtenderImpl.getProcessorType 來指定處理器類型 如下所述:

  • PROCESSOR_TYPE_NONE無處理器。相片會在相機中處理 HAL。

  • PROCESSOR_TYPE_REQUEST_UPDATE_ONLY處理器類型可讓您 更新重複要求,根據新的 最新的 TotalCaptureResult

    PreviewExtenderImpl.getProcessor 必須傳回 RequestUpdateProcessorImpl 這個例項會處理 TotalCaptureResult 例項並傳回 用於更新重複要求的 CaptureStageImpl 執行個體。 PreviewExtenderImpl.getCaptureStage() 也應該反映 並傳回最新的 CaptureStageImpl

  • PROCESSOR_TYPE_IMAGE_PROCESSOR這個類型可讓您 處理 YUV_420_888 張圖片並將輸出內容 PRIVATE 介面。

    您必須實作並傳回 PreviewImageProcessorImpl敬上 執行個體 (在 PreviewExtenderImpl.getProcessor 中)。處理方需 來處理 YUV_420_888 個輸入圖片。指令應該會將輸出內容寫入 預覽畫面的 PRIVATE 格式。Camera2/X 改為使用 YUV_420_888 介面 PRIVATE來設定預覽 CameraCaptureSession

    請參閱下圖的流程示意圖:

預覽處理器

圖 6. 使用「PreviewImageProcessorImpl」預覽流程

PreviewImageProcessorImpl 介面擴充 ProcessImpl,並 三個重要方法:

  • onOutputSurface(Surface surface, int imageFormat) 會設定輸出介面 以便處理處理器的難題對於 PreviewImageProcessorImplimageFormat 是像素 格式,例如 PixelFormat.RGBA_8888

  • onResolutionUpdate(Size size) 會設定輸入圖片的大小。

  • onImageFormatUpdate(int imageFormat) 會設定輸入的圖片格式 圖片。目前只能設為 YUV_420_888

圖片擷取處理器

如要繼續進行擷取,您可以傳回 CaptureProcessorImpl敬上 使用 ImageCaptureExtenderImpl.getCaptureProcessor 建立執行個體處理器 負責處理拍攝的 YUV_420_888 圖片清單 TotalCaptureResult 執行個體,並將輸出內容寫入 YUV_420_888 介面。

您可放心假設預覽已啟用且正在執行,然後再傳送 仍會擷取要求

請參閱下圖的流程:

擷取處理器

圖 7. 仍然使用 CaptureProcessorImpl 擷取流程

  1. Camera2/X 會使用 YUV_420_888 格式介面進行靜態擷取設定 擷取工作階段Camera2/X 藉由呼叫以下指令來準備 CaptureProcessorImpl

    • YUV_420_888會員價 CaptureProcessorImpl.onImageFormatUpdate()
    • CaptureProcessorImpl.onResolutionUpdate() 替換為輸入的圖片大小。
    • 輸出為 YUV_420_888CaptureProcessorImpl.onOutputSurface() 途徑。
  2. ImageCaptureExtenderImpl.getCaptureStages 會傳回一系列 CaptureStageImpl ,其中每個元素都會對應至包含擷取參數的 CaptureRequest 例項 以及由 Camera2/X 傳送的資料舉例來說,假設傳回的清單包含三個 CaptureStageImpl 例項,Camera2/X 會傳送三個擷取要求, 對應的擷取參數 captureBurst 也能使用 Google Cloud CLI 或 Compute Engine API

  3. 收到的映像檔和 TotalCaptureResult 個執行個體已組合在一起 並傳送到「CaptureProcessorImpl」進行處理。

  4. CaptureProcessorImpl 會將結果圖片 (YUV_420_888 格式) 寫入 onOutputSurface() 呼叫指定的輸出介面。Camera2/X 可將相機轉換成 轉換成 JPEG 圖片

支援擷取要求金鑰和結果

除了相機預覽和拍攝外,應用程式也能設定縮放功能, Flash 參數,或觸發輕觸對焦功能。這些參數 以配合您的擴充功能導入作業

下列方法已加入 extensions-interface 1.3.0,以便 可以公開實作支援的參數:

  • ImageCaptureExtenderImpl.getAvailableCaptureRequestKeys() 會傳回 擷取導入作業支援的要求金鑰。
  • ImageCaptureExtenderImpl.getAvailableCaptureResultKeys() 會傳回 擷取結果中包含的結果鍵。

如果相機 HAL 處理擴充功能,Camera2/X 就會擷取相片。 結果為 CameraCaptureSession.CaptureCallback。不過, 實作處理器後,Camera2/X 會在 ProcessResultImpl敬上 ,傳遞至 process() 方法 PreviewImageProcessorImplCaptureProcessorImpl。 使用者由您自行製作報表 透過 ProcessResultImpl 到 Camera2/X。

請看以下範例,瞭解 CaptureProcessorImpl 介面的定義。 在 extensions-interface 1.3.0 以上版本中,系統會叫用第二個 process() 呼叫:

Interface CaptureProcessorImpl extends ProcessorImpl {
    // invoked when extensions-interface version < 1.3.0
    void process(Map<Integer, Pair<Image, TotalCaptureResult>> results);
    // invoked when extensions-interface version >= 1.3.0
    void process(Map<Integer, Pair<Image, TotalCaptureResult>> results,
            ProcessResultImpl resultCallback, Executor executor);
}

執行縮放、輕觸對對焦、閃光燈和曝光等常見的相機操作 補償,建議您同時支援以下鍵和值 要求及擷取結果:

  • 縮放:
    • CaptureRequest#CONTROL_ZOOM_RATIO
    • CaptureRequest#SCALER_CROP_REGION
  • 輕觸對焦:
    • CaptureRequest#CONTROL_AF_MODE
    • CaptureRequest#CONTROL_AF_TRIGGER
    • CaptureRequest#CONTROL_AF_REGIONS
    • CaptureRequest#CONTROL_AE_REGIONS
    • CaptureRequest#CONTROL_AWB_REGIONS
  • Flash:
    • CaptureRequest#CONTROL_AE_MODE
    • CaptureRequest#CONTROL_AE_PRECAPTURE_TRIGGER
    • CaptureRequest#FLASH_MODE
  • 曝光補償:
    • CaptureRequest#CONTROL_AE_EXPOSURE_COMPENSATION

針對實作 1.2.0 以下版本的基本擴充器,CameraX Extensions API 明確支援上述所有金鑰。適用對象 extensions-interface 1.3.0,CameraX 和 Camera2 都會遵循傳回的清單 而且僅支援其中包含的鍵舉例來說,假設您決定返回 只有CaptureRequest#CONTROL_ZOOM_RATIO和 1.3.0 實作中的 CaptureRequest#SCALER_CROP_REGION,則 意即只有在輕觸對焦、閃光燈和曝光時,應用程式才支援縮放功能 不允許提供報酬。

進階擴展器

進階擴展器是一種以 Camera2 API 為基礎的廠商實作方式。 這個延伸器類型已新增至 extensions-interface 1.2.0 版。視乎 可在應用程式層實作擴充功能 實際情況取決於下列因素:

  • 自訂串流設定:調整 RAW 串流等自訂串流 也可以為不同的實體攝影機 ID 設定多個串流

  • 傳送 Camera2 要求的功能:支援複雜的互動 這個邏輯可以根據 先前的要求

進階延伸器會提供包裝函式或中繼層, 自訂串流設定,視需求傳送擷取要求。

要實作的檔案

如要切換至進階擴展器實作, 有 isAdvancedExtenderImplemented() 種方法 ExtensionVersionImpl 必須傳回 true。原始設備製造商 (OEM) 必須為每種擴充功能類型導入 對應的延伸模組類別。進階延伸器實作檔案 Advanced 套件中的相關說明。

要實作的擴充類別
夜晚 advanced/NightAdvancedExtenderImpl.java
高動態範圍 advanced/HdrAdvancedExtenderImpl.java
汽車 advanced/AutoAdvancedExtenderImpl.java
散景 advanced/BokehAdvancedExtenderImpl.java
修容 advanced/BeautyAdvancedExtenderImpl.java

在下方範例中,我們會使用 AdvancedExtenderImpl 做為預留位置。 將您要的副檔名替換成該擴充功能的擴充檔案名稱 實作。

一起來看看 Camera2/X 如何叫用 extensions-interface 來完成這三項工作 應用程式流程

應用程式流程 1:檢查擴充功能是否可用

進階應用程式 Flow1

圖 8. 進階擴展器上的應用程式流程 1

首先,應用程式會檢查是否支援指定的擴充功能。

應用程式流程 2:查詢資訊

進階應用程式 Flow2

圖 9.進階擴展器的應用程式流程 2

呼叫 AdvancedExtenderImpl.init() 後,應用程式即可查詢 參考 AdvancedExtenderImpl 的資訊:

  • 預估仍會擷取延遲時間: AdvancedExtenderImpl.getEstimatedCaptureLatencyRange() 會傳回範圍 讓應用程式評估其是否適合 為目前情境啟用擴充功能。

  • 預覽和靜態擷取支援的解析度:

    • AdvancedExtenderImpl.getSupportedPreviewOutputResolutions() 會傳回地圖 圖片格式對應至預覽途徑格式支援的尺寸清單 而且大小和大小原始設備製造商 (OEM) 必須支援至少 PRIVATE 格式。

    • AdvancedExtenderImpl.getSupportedCaptureOutputResolutions() 會傳回 仍擷取表面支援的格式和大小。原始設備製造商 (OEM) 必須同時支援 JPEGYUV_420_888 格式輸出內容。

    • AdvancedExtenderImpl.getSupportedYuvAnalysisResolutions() 會傳回 支援的大小YUV_420_888圖片分析如果 不支援圖片分析 YUV 表面 getSupportedYuvAnalysisResolutions() 應傳回 null 或空白清單。

  • 可用的擷取要求金鑰/結果 (在 extensions-interface 1.3.0 中加入): Camera2/X 會叫用下列方法,擷取支援的拍攝作業 從您的實作要求金鑰和結果鍵:

    • AdvancedExtenderImpl.getAvailableCaptureRequestKeys
    • AdvancedExtenderImpl.getAvailableCaptureResultKeys

若需更多資訊,請參閲 支援擷取要求金鑰和結果

應用程式流程 3:在啟用擴充功能的情況下預覽/仍擷取

進階應用程式 Flow3

圖 10. 進階擴展器的應用程式流程 3

上圖顯示開始預覽以及目前仍擷取的主要流程 「進階延伸器」類型以下將逐一介紹每個步驟。

  1. SessionProcessorImpl 執行個體

    核心進階延伸器的核心實作位於 SessionProcessorImpl, 負責提供自訂工作階段設定 擷取要求來啟動預覽並仍然擷取要求。 系統會叫用 AdvancedExtenderImpl.createSessionProcessor(),以傳回 SessionProcessorImpl 執行個體。

  2. initSession

    SessionProcessorImpl.initSession() 會初始化擴充功能的工作階段。 您可以在這裡分配資源並傳回工作階段設定 正在準備 CameraCaptureSession

    針對輸入參數,Camera2/X 會指定輸出表面設定 用於預覽、靜態拍攝,以及選用的 YUV 影像分析這個輸出結果 介面設定 (OutputSurfaceImpl) 包含介面、尺寸和圖片 擷取自 AdvancedExtenderImpl 中的方法:

    • getSupportedPreviewOutputResolutions()
    • getSupportedCaptureOutputResolutions()
    • getSupportedYuvAnalysisResolutions()

    您必須傳回 Camera2SessionConfigImpl 例項,其中包含 列出 Camera2OutputConfigImpl 執行個體和所用工作階段參數的清單 來設定 CameraCaptureSession。您必須負責 將正確的相機影像輸出到 Camera2/X。以下列舉幾個啟用輸出的選項:

    • 在相機 HAL 中進行處理:您可以直接新增輸出介面 到CameraCaptureSession使用 SurfaceOutputConfigImpl 。這會設定為相機提供的輸出介面 管道並允許相機 HAL 處理圖片
    • 處理中繼 ImageReader 介面 (RAW、YUV 等):新增 中階ImageReader介面和CameraCaptureSession介面, ImageReaderOutputConfigImpl 執行個體。

      您需要處理中繼圖片並將結果圖片寫入

    ,瞭解如何調查及移除這項存取權。
    • 使用 Camera2 介面分享功能:與其他介面一起使用表面分享功能 方法是將任何 Camera2OutputConfigImpl 例項新增至 另一個 getSurfaceSharingOutputConfigs() 方法 Camera2OutputConfigImpl 執行個體。表面格式和大小必須 完全相同。

    所有 Camera2OutputConfigImpl,包括 SurfaceOutputConfigImplImageReaderOutputConfigImpl 必須有一個專屬 ID (getId()),也就是 用於指定目標介面及從 ImageReaderOutputConfigImpl

  3. onCaptureSessionStartRequestProcessorImpl

    CameraCaptureSession 啟動且相機架構叫用時 onConfigured(),然後 Camera2/X 叫用 回應 Camera2 要求時為 SessionProcessorImpl.onCaptureSessionStart() 包裝函式 RequestProcessImpl。Camera2/X 實作 RequestProcessImpl。 可讓您執行擷取要求,以及 如果使用 ImageReaderOutputConfigImpl,則會擷取圖片

    RequestProcessImpl API 與 Camera2 類似 CameraCaptureSession API 來處理要求。兩者的差異如下:

    • 目標介面是以 Camera2OutputConfigImpl 執行個體。
    • 擷取 ImageReader 圖片的功能。

    您可以呼叫 RequestProcessorImpl.setImageProcessor(), 使用 Camera2OutputConfigImpl ID 註冊 ImageProcessorImpl 例項,以便 接收圖片。

    RequestProcessImpl 例項會在 Camera2/X 呼叫之後失效 SessionProcessorImpl.onCaptureSessionEnd()

  4. 開始預覽並拍照

    在進階延伸器實作中,您可以傳送擷取要求 透過 RequestProcessorImpl 介面取得。Camera2/X 會通知你 開始重複預覽或靜態擷取序列 呼叫 SessionProcessorImpl#startRepeatingSessionProcessorImpl#startCapture。請傳送 才能滿足這些預覽和仍在擷取要求

    Camera2/X 也會透過設定擷取要求參數 SessionProcessorImpl#setParameters。您必須設定這些要求參數 (如果支援參數)。

    至少必須支援 CaptureRequest.JPEG_ORIENTATIONCaptureRequest.JPEG_QUALITYextensions-interface 1.3.0 支援要求 以及結果鍵。這些符記會由下列方法公開:

    • AdvancedExtenderImpl.getAvailableCaptureRequestKeys()
    • AdvancedExtenderImpl.getAvailableCaptureResultKeys()

    當開發人員在 getAvailableCaptureRequestKeys 清單中設定鍵時, 請務必啟用參數,並確保擷取 結果包含 getAvailableCaptureResultKeys 清單中的鍵。

  5. startTrigger

    系統會叫用 SessionProcessorImpl.startTrigger() 來啟動這個觸發條件, 以 CaptureRequest.CONTROL_AF_TRIGGERCaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER。您可以忽略任何 擷取未聲稱的請求金鑰 AdvancedExtenderImpl.getAvailableCaptureRequestKeys()

    extensions-interface 1.3.0 版起,支援 startTrigger()。這項服務 可讓應用程式導入含有擴充功能的輕觸對焦和閃光燈功能。

  6. 清理

    完成擷取工作階段後 系統會在關閉前叫用 SessionProcessorImpl.onCaptureSessionEnd() CameraCaptureSession。擷取工作階段關閉後 deInitSession() 會執行清除作業。

支援預覽、靜態擷取和圖片分析功能

您應該為預覽套用擴充功能,但仍要擷取用途。 不過,如果延遲時間太高,因而無法流暢顯示預覽,您可以 套用延伸模組,以便進行靜態擷取。

針對「基本延伸模組」類型,無論是否啟用預覽的擴充功能, 您必須同時實作 ImageCaptureExtenderImplPreviewExtenderImpl 特定擴充功能的狀態應用程式通常會使用 YUV 串流來分析 圖片內容,例如尋找 QR code 或文字為這個用途提供更完善的支援 ,您應支援預覽串流組合,但仍擷取和 用於設定「CameraCaptureSession」的 YUV_420_888 個串流。也就是說 如果實作處理器,就必須支援串流 三個 YUV_420_888 串流的組合。

對於進階延伸器,Camera2/X 會將三個輸出介面傳遞至 SessionProcessorImpl.initSession() 呼叫。這些輸出介面可供預覽 、靜態拍攝和圖片分析。請務必確保預覽 但仍會擷取輸出內容介面,則會顯示有效的輸出內容不過,對於映像檔 分析輸出介面,確保只有非空值時才能正常運作。如果您的 無法支援圖片分析串流,您可以傳回空白 清單。AdvancedExtenderImpl.getSupportedYuvAnalysisResolutions()。這個 可確保圖片分析輸出介面一律為空值 SessionProcessorImpl.initSession()

支援視訊擷取功能

目前的 Camera Extension 架構僅支援預覽,且仍支援靜態模式 或擷取用途我們不支援在 MediaCodec上啟用擴充功能 或是 MediaRecorder 介面,用於錄製影片。不過 ,讓應用程式錄製預覽輸出內容

我們正在調查支援「MediaCodec」和「MediaRecorder」平台。

擴充功能專用的中繼資料

Android 14 以上版本適用的擴充功能專屬中繼資料 可讓相機擴充功能用戶端設定及接收擴充功能的特定擷取作業 要求設定和結果具體來說,相機擴充功能 用戶端可以使用 EXTENSION_STRENGTH 擷取要求參數來控制 擴充功能強度和 EXTENSION_CURRENT_TYPE 擷取結果,以便 指出已啟用的擴充功能類型。

擷取要求

EXTENSION_STRENGTH敬上 擷取要求參數 控制擴充功能後續處理效果的強度。對應的 如果未設定這個參數,則擷取結果會包含預設強度值 由用戶端明確指定。您可以按照以下方式套用此參數: 擴充功能類型:

  • BOKEH:控制模糊程度。
  • HDRNIGHT:控制融合的圖片數量和亮度 成品
  • FACE_RETOUCH:控管化妝品和膚色的強度 平滑

EXTENSION_STRENGTH 參數支援的範圍介於 0 至 之間 100,其中 0 表示未處理擴充功能或簡易直通式 100:表示處理效果的最大強度。

如要新增對「EXTENSION_STRENGTH」的支援,請使用供應商 擴充功能程式庫 1.3.0 版中引入的特定參數 API 存取 API若需更多資訊,請參閲 getAvailableCaptureRequestKeys()

擷取結果

EXTENSION_CURRENT_TYPE敬上 擷取結果可讓擴充功能實作通知用戶端, 。

因為使用 AUTO 類型的擴充功能會在各個擴充功能之間動態切換 例如 HDRNIGHT 等類型,視場景條件而定,相機 擴充功能應用程式可以使用 EXTENSION_CURRENT_TYPE,顯示 「AUTO」擴充功能選取的現有擴充功能。

預估即時靜態擷取延遲時間

針對 Android 14 以上版本,相機擴充功能用戶端 即時查詢仍會根據情境 環境條件 getRealtimeStillCaptureLatency()。這個 方法提供的預估值,會比靜態資料中的 getEstimatedCaptureLatencyRangeMillis()敬上 方法。根據預估延遲時間,應用程式可以決定略過擴充功能 或顯示指示通知使用者 執行中作業

CameraExtensionSession.StillCaptureLatency latency;

latency = extensionSession.getRealtimeStillCaptureLatency();

// The capture latency from ExtensionCaptureCallback#onCaptureStarted() until ExtensionCaptureCallback#onCaptureProcessStarted().

latency.getCaptureLatency();

// The processing latency from  ExtensionCaptureCallback#onCaptureProcessStarted() until  the processed frame returns to the client.

latency.getProcessingLatency();

如要支援即時擷取預估延遲時間,請採用 包括:

擷取處理進度回呼

針對 Android 14 以上版本,相機擴充功能用戶端 可以接收長時間執行仍持續擷取處理程序的回呼 作業。應用程式可以向使用者顯示目前進度,以改善 整體使用者體驗

應用程式可以使用下列程式碼整合這項功能:

import android.hardware.camera2.CameraExtensionSession.
ExtensionCaptureCallback;

{
…
  class AppCallbackImpl extends ExtensionCaptureCallback {
…
    @Override
    public void onCaptureProcessProgressed(
      @NonNull CameraExtensionSession session,
      @NonNull CaptureRequest request,
      @IntRange(from = 0, to = 100) int progress) {
      // Update app UI with current progress
    }
  }
…
}

為了支援擷取處理進度回呼,擴充功能供應商 實作必須呼叫下列含有目前進度的回呼 值:

貼文檢視畫面靜態擷取

在 Android 14 以上版本中,相機擴充功能可以 使用 setPostviewOutputConfiguration。 為改善使用者體驗,應用程式可將貼文畫面圖片顯示為 預留位置, 並在最終圖片可用時替換圖片。應用程式設定 ,並使用以下參考代碼發出瀏覽後轉換擷取要求:

{
…
if (!CameraExtensionCharacteristics.isPostviewAvailable()) {
    continue;
}
…
ExtensionSessionConfiguration extensionConfiguration = new
        ExtensionSessionConfiguration(
                CameraExtensionCharacteristics.EXTENSION_NIGHT,
                outputConfig,
                backgroundExecutor,
                extensionSessionStateCallback
    );

extensionConfiguration.setPostviewOutputConfiguration(
    postviewImageOutput);
…
CaptureRequest.Builder captureRequestBuilder =
    cameraDevice.createCaptureRequest(
        CameraDevice.TEMPLATE_STILL_CAPTURE);
captureRequestBuilder.addTarget(stillImageReader.getSurface());
captureRequestBuilder.addTarget(postviewImageSurface);

CaptureRequest captureRequest = captureRequestBuilder.build();
…
}

如要支援「瀏覽後擷取」功能,您的供應商導入方式必須導入 包括:

支援 SurfaceView 輸出

針對 Android 14 以上版本,相機擴充功能用戶端 藉由註冊 SurfaceView敬上 重複要求的預覽輸出內容。

如要支援 SurfaceView 輸出功能,就必須導入供應商擴充功能。 您能夠對 SurfaceView 執行個體串流及輸出預覽。目的地: 請確認這是受支援的瀏覽器,請執行 SurfaceViewExtensionPreviewTest.java CTS 模組。

供應商專屬工作階段類型

這項功能可讓廠商擴充功能實作,選取廠商專屬工作階段類型 (會在內部相機擷取工作階段中設定),而不是使用預設值。

功能完全在架構和供應商堆疊中運作,不會對用戶端/公開造成的 API 影響。

如要選取供應商專屬的工作階段類型,請為您的擴充功能程式庫實作下列程式碼: * 適用於基本額外資訊:ExtenderStateListener.onSessionType() * Camera2SessionConfigImpl.getSessionType() 適用於進階擴充功能

擴充功能介面版本記錄

下表列出 Camera Extension 介面的版本記錄。個人中心 請一律以最新版本導入供應商程式庫。

版本 新增的功能
1.0.0 版
  • 版本驗證
    • ExtensionVersionImpl
  • 基本延長線
    • PreviewExtenderImpl
    • ImageCaptureExtenderImpl
    • Processor
      • PreviewImageProcessorImpl
      • CaptureProcessorImpl
      • RequestUpdateProcessorImpl
1.1.0 版
  • 程式庫初始化
    • InitializerImpl
  • 公開支援的解析度
    • PreviewExtenderImpl.getSupportedResolutions
    • ImageCaptureExtenderImpl.getSupportedResolutions
1.2.0 版
  • 進階延伸器
    • AdvancedExtenderImpl
    • SessionProcessorImpl
  • 取得預估擷取延遲時間
    • ImageCaptureExtenderImpl.getEstimatedCaptureLatencyRange
1.3.0 版
  • 公開支援的擷取要求金鑰/結果金鑰
    • ImageCaptureExtenderImpl.getAvailableCaptureRequestKeys」和「getAvailableCaptureResultKeys
    • AdvancedExtenderImpl.getAvailableCaptureRequestKeys」和「getAvailableCaptureResultKeys
    • 新的 process() 呼叫,會在 PreviewImageProcessorImplCaptureProcessorImpl 中使用 ProcessResultImpl
    • 支援觸發條件類型要求
      • AdvancedExtenderImpl.startTrigger
1.4.0 版
  • 擴充功能專用的中繼資料
  • 動態靜態擷取延遲時間預估值
  • 擷取處理進度回呼
  • 貼文檢視畫面靜態擷取
  • 支援 SurfaceView 輸出
  • 供應商專屬工作階段類型

參照實作

以下提供參考原始設備製造商 (OEM) 供應商程式庫實作項目: frameworks/ex

  • advancedSample:進階延伸器的基本實作。

  • sample:基本擴充程式的基本實作。

  • service_based_sample:示範如何代管主機的實作 相機擴充功能 Service。 這項實作包含以下元件:

    • oem_library: 適用於 Camera2 和 CameraX Extensions API 的 Camera Extensions OEM 程式庫 實作 Extensions-Interface。就如同 將 Extensions-Interface 的來電轉接至服務。這個圖書館 也提供 AIDL 檔案和包裝函式類別,用來與 課程中也會快速介紹 Memorystore 這是 Google Cloud 的全代管 Redis 服務

      進階延伸器預設為啟用。如要啟用基本延伸功能, 變更ExtensionsVersionImpl#isAdvancedExtenderImplemented即可退貨 false

    • extensions_service: 擴充功能服務的實作範例。新增實作方式 此處。在服務中實作的介面類似 至 Extensions-Interface。舉例來說,將 IAdvancedExtenderImpl.Stub 執行的作業與 AdvancedExtenderImplImageWrapperTotalCaptureResultWrapper 是 以便將 ImageTotalCaptureResult 設為可封裝。

在裝置上設定供應商庫

應用程式並未內建 OEM 供應商程式庫。它是從裝置載入 在 Camera2/X 的執行階段期間播放。在 CameraX 中,<uses-library> 標記會宣告 androidx.camera.extensions.impl 程式庫 (在 AndroidManifest.xml敬上 camera-extensions 程式庫的檔案,是 CameraX 的依附元件,且必須 並在執行階段載入。在 Camera2 中,架構會載入擴充功能服務 並宣告 <uses-library> 載入相同的 androidx.camera.extensions.impl 程式庫。

這項操作會允許使用擴充功能的第三方應用程式,自動載入原始設備製造商 (OEM) 以及供應商程式庫OEM 程式庫標示為選用,以便在裝置上執行應用程式 但裝置上沒有資料庫 當應用程式嘗試使用相機時,Camera2/X 會自動處理此行為 擴充功能只要裝置製造商將 OEM 程式庫放在 以便應用程式找到該裝置。

如要在裝置上設定 OEM 程式庫,請按照下列步驟操作:

  1. 新增 <uses-library> 標記所需的權限檔案, 格式如下: /etc/permissions/ANY_FILENAME.xml。適用對象 例如:/etc/permissions/camera_extensions.xml。當中的檔案 目錄提供 <uses-library> 中命名程式庫的對應關係 裝置上的實際檔案路徑
  2. 請參考以下範例,在檔案中加入必要資訊。

    • name 須為 androidx.camera.extensions.impl,因為 是 CameraX 搜尋的程式庫
    • file 是包含 擴充功能實作 (例如 /system/framework/androidx.camera.extensions.impl.jar)。
    <?xml version="1.0" encoding="utf-8"?>
    <permissions>
        <library name="androidx.camera.extensions.impl"
                 file="OEM_IMPLEMENTED_JAR" />
    </permissions>
    

在 Android 12 以上版本中,支援 CameraX 的裝置 擴充功能的 ro.camerax.extensions.enabled 屬性必須設為 true。 可查詢裝置是否支援擴充功能。 方法是在裝置的 make 檔案中加入以下這一行:

PRODUCT_VENDOR_PROPERTIES += \
    ro.camerax.extensions.enabled=true \

驗證

如要在 請使用位於 androidx-main/camera/integration-tests/extensionstestapp/、 針對各種供應商提供的額外資訊

完成導入後,請使用 相機擴充功能驗證工具 執行自動化和手動測試,確認供應商程式庫 正確實作。

擴充場景模式與相機擴充功能的比較

就散景擴充功能而言, 除了透過相機擴充功能公開外, 可以使用擴充場景模式公開擴充功能,方法是先啟用 這個 CONTROL_EXTENDED_SCENE_MODE敬上 鍵。 如要進一步瞭解實作詳情,請參閱「相機散景」。

與相機擴充功能相比,擴充場景模式的限制較少 相機應用程式。例如,您可以在下列情況中啟用延伸場景模式: 支援彈性串流的一般 CameraCaptureSession 執行個體 組合及擷取請求參數相較之下,相機擴充功能 僅支援一組固定的串流類型,且對擷取功能的支援有限 請求參數

延伸場景模式的缺點是只能在 也就是相機 HAL 必須通過驗證才能運作 應用程式開發人員可以使用的雙向控制選項

建議您同時使用延伸場景模式和相機,顯露散景效果 擴充功能,因為應用程式可能會偏好使用特定 API 啟用散景。 建議您先使用延伸場景模式,因為這是 讓應用程式更靈活地啟用散景擴充功能接著,您就能將 根據延伸場景模式產生的相機擴充功能介面。如果導入 相機 HAL 的散景很困難,例如需要貼文才能進行 在應用程式層內運作的處理器,以便處理圖片,因此建議您導入 透過「Camera Extensions」介面使用散景擴充功能。

常見問題 (FAQ)

API 級別是否有任何限制?

可以。這取決於原始設備製造商 (OEM) 所需的 Android API 功能集 供應商程式庫實作。例如: ExtenderStateListener.onPresetSession() 會使用 SessionConfiguration.setSessionParameters() 呼叫來設定基準代碼。這項呼叫僅適用於 API 級別 28 以上版本。如要進一步瞭解特定介面方法,請參閱 API 參考說明文件