使用 CameraX Extensions API 將特效應用到照片上

Android開發者發表於2021-11-03

Android CameraX 的設計旨在幫助您簡化相機應用的開發工作。隨著對 CameraX 不斷的開發,相機應用的開發者們向我們展示了他們的激情和熱忱,當前的 API 中已經融入了許多很棒的創意,例如值得稱讚的 CameraX Extensions API。最近我們採納了開發者社群的意見,對擴充套件進行了重構,如今有了新的 ExtensionsManager,您只需兩行程式碼就可以使用這些擴充套件!本文將介紹如何在您的應用中使用 Extensions API。

CameraX Extensions

Android 裝置配備了強大的相機,製造商們投入了大量精力將眾多前沿的功能特性或特效融入這些相機裝置中。過去,這些強大的功能只能由裝置的原生相機應用提供。如今,憑藉 CameraX Extensions API,第三方開發者可以通過一個通用的、簡單的介面來訪問這些強大的相機功能。

CameraX Extensions 涵蓋的內容

1.0.0 版本的 CameraX Extensions 包括一些最常見的內建相機特效:

  • BOKEH (焦外成像): 在人像模式下拍攝照片時,讓前景人物更清晰。
  • HDR (高動態範圍): 拍照時使用不同的自動曝光 (AE) 配置,以獲得最佳效果。
  • NIGHT (夜間): 在低照度環境下 (通常是在夜間) 捕獲最佳靜態影像。
  • FACE RETOUCH (臉部照片修復): 拍攝靜態影像時,修飾臉部膚色、輪廓等。
  • AUTO (自動): 根據周圍的景色自動調整最終影像。

讓我們來看幾組在 Android 手機上拍攝的照片,拍照時分別啟用和禁用了由 CameraX Extensions API 提供的特效。

BOKEH 模式的例子

△ 圖 1: 右側照片啟用了 BOKEH 特效。

△ 圖 1: 右側照片啟用了 BOKEH 特效。

HDR 模式的例子

△ 圖 2: 右側照片啟用了 HDR 特效。

△ 圖 2: 右側照片啟用了 HDR 特效。

NIGHT 模式例子

△ 圖 3: 右側照片啟用了 NIGHT 特效。

△ 圖 3: 右側照片啟用了 NIGHT 特效。

視覺上的差異是很明顯的。您可以使用 CameraX Extensions API 在您自己的應用中實現這些影像的效果。

現在讓我們看看如何將 CameraX 的 API 整合到您的應用中。

Extensions API

在現有的 CameraX 應用中,首先您可以引入 camera-extensions Jetpack 庫來新增 CameraX Extensions:

dependencies {
    // 與 Extensions 庫版本號相匹配的 CameraX 核心庫
    implementation 'androidx.camera:camera-core:1.1.0-alpha08'
    implementation 'androidx.camera:camera-camera2:1.1.0-alpha08'
    implementation 'androidx.camera:camera-lifecycle:1.1.0-alpha08'

    // CameraX Extensions 庫
    implementation 'androidx.camera:camera-extensions:1.0.0-alpha28'

    // 其他依賴項
    implementation('androidx.concurrent:concurrent-futures-ktx:1.1.0')
        …
}

接下來,通過以下步驟整合 Extensions:

  1. 獲取 ExtensionsManager 例項。
  2. 檢查目標裝置是否支援需要用到的擴充套件模式;
  3. 獲取一個啟用擴充套件的 CameraSelector;
  4. 使用啟用擴充套件的 CameraSelector 呼叫 bindToLifecycle)。

獲取 ExtensionsManager 例項

第一步是用擴充套件庫的 getInstance(Context)) API 獲得一個 ExtensionsManager 例項。這個 API 返回一個 ListenableFuture,我們可以在 Kotlin 掛起函式中使用 await() 來獲取結果以避免阻塞主執行緒。(注意: 在 ListenableFuture 上使用 await() 須引入 androidx.concurrent:concurrent-futures-ktx: 1.1.0 依賴項。)

// 建立擴充套件管理器(使用 Jetpack Concurrent 庫)
val extensionsManager =  ExtensionsManager.getInstance(context).await()

通過 ExtensionsManager,您可以確定裝置是否支援某一特定的擴充套件模式,併為其獲取一個啟用擴充套件的 CameraSelector。請注意以下幾點:

  • ExtensionsManager 是一個程式範圍的全域性資源: 一個程式中只存在一個 ExtensionsManager 例項。
  • ExtensionsManager 始終存在: 無論底層裝置是否支援擴充套件,CameraX 都提供一個有效的 ExtensionsManager 例項。

檢查擴充套件模式可用性

通過 ExtensionsManager,使用 isExtensionAvailable(CameraProvider, CameraSelector, int)) 函式檢查擴充套件的可用性: 如果裝置上存在任何經由 CameraSelector 過濾的相機支援所查詢的擴充套件,則返回 true,否則返回 false。

// 獲取相機裝置來檢查是否支援擴充套件
val cameraSelector = CameraSelector.DEFAULT_BACK_CAMERA

// 檢查是否支援 BOKEH
 if (extensionsManager.isExtensionAvailable(
    cameraProvider,
    cameraSelector,
    ExtensionMode.BOKEH
   )) {
   ...
}

獲取啟用擴充套件的 CameraSelector

一旦您確認了裝置支援該擴充套件模式,就可以用 getExtensionEnabledCameraSelector(CameraProvider, CameraSelector, int)) 函式獲取一個啟用擴充套件的 CameraSelector。此函式返回啟用擴充套件的 CameraSelector,其包含關於指定擴充套件模式的所有詳細資訊。

val bokehCameraSelector = extensionsManager
                          .getExtensionEnabledCameraSelector(
                              cameraProvider, cameraSelector, ExtensionMode.BOKEH)

使用啟用擴充套件的 CameraSelector 呼叫 bindToLifecycle()

最後一步是使用 bindToLifecycle()) 將您的用例與啟用擴充套件的 CameraSelector 繫結。使用啟用擴充套件的 CameraSelector 如同使用普通的 CameraSelector 一樣,例如使用 DEFAULT_BACK_CAMERADEFAULT_FRONT_CAMERA。當使用啟用擴充套件的 CameraSelector繫結用例時,CameraX 會直接在相機上啟用指定的擴充套件模式。例如,當繫結到 Preview 時,擴充套件效果被應用到預覽中,或者應用到由所繫結的 ImageCapture 所捕獲的影像上。

// 將開啟了 BOKEH 的相機選擇器繫結到用例上
val imageCapture = ImageCapture.Builder().build()
val preview = Preview.Builder().build()
cameraProvider.bindToLifecycle(
                lifecycleOwner,
                bokehCameraSelector,
                imageCapture,
                preview
            )

使用 Extensions API 的樣例程式碼

Extensions API 示例的完整程式碼如下:

fun onCreate() {
    lifecycleScope.launch {
        // 建立 cameraProvider
        val cameraProvider = ProcessCameraProvider.getInstance(context).await() 

        // 建立 extensionsManager(使用 Jetpack Concurrent 庫)
        val extensionsManager = 
                ExtensionsManager.getInstance(context).await()

        // 獲取相機裝置來檢查是否支援擴充套件        
        val cameraSelector = CameraSelector.DEFAULT_BACK_CAMERA

        // 檢查是否支援 BOKEH
        if (extensionsManager.isExtensionAvailable(
                cameraProvider,
                cameraSelector,
                ExtensionMode.BOKEH
            )) {
            // 在啟用不同擴充套件模式之前解除所有用例的繫結
            cameraProvider.unbindAll()

            // 獲取啟用了 BOKEH 的相機選擇器
            val bokehCameraSelector = extensionsManager
                    .getExtensionEnabledCameraSelector(
                cameraProvider,
                cameraSelector,
                ExtensionMode.BOKEH
            )

            // 將開啟了 BOKEH 的相機選擇器繫結到用例上
            val imageCapture = ImageCapture.Builder().build()
            val preview = Preview.Builder().build()
            cameraProvider.bindToLifecycle(
                lifecycleOwner,
                bokehCameraSelector,
                imageCapture,
                preview
            )
        }
    }
}

Extensions API 對核心模組的依賴

CameraX Extensions API 是在 camera-extensions 庫中實現的,並且它依賴 CameraX 核心模組 (core、camera2 和 lifecycle)。使用 CameraX Extensions 時,請務必使用與您正在使用的 CameraX 核心模組 相同的釋出包 中的版本。例如,要使用 camera-extensions:1.0.0-alpha28,則您必須在應用的依賴列表中包含 1.0.0-alpha08 版本的 camera-lifecyclecamera-corecamera-camera2,因為它們是於 2021 年 8 月 18 日在同一軟體包中釋出的。

支援擴充套件的裝置

為了能使用 CameraX Extensions API,裝置製造商需要實現 CameraX Vendor Extensions 介面。您可以在 CameraX 裝置頁面 上找到支援 CameraX Extensions API 的部分裝置列表。請注意,這不是一個詳盡的列表。如果您的裝置被列出,但可用性檢查返回了 false,您可能需要將您的裝置更新到製造商的最新 ROM 版本。

除了支援擴充套件的裝置列表外,從 Android 12 開始,您還可以通過檢查 Android 屬性 ro.camerax.extensions.enabled 來確定裝置是否支援 CameraX Extensions。

移除舊版 Extensions API

2019 年 8 月釋出的舊版 Extensions API 現已廢棄。這個舊版的 Extensions API 提供了擴充套件器類,需要將擴充套件相關的配置應用到每個 Preview 和 ImageCapture 用例上。舊版的擴充套件器設計可能會導致開發人員忘記要在 Preview 或 ImageCapture 上啟用擴充套件模式,並可能導致非預期的行為。

新的 CameraX Extensions 庫在 1.0.0-alpha26 中引入。較新的 Extensions API 將擴充套件繫結從用例切換到目標相機,使用起來更加方便。請務必遷移以利用新的 Extensions API。

我們特別感謝那些幫助實現 CameraX Extensions API 的出色的 Android 相機開發者和裝置製造商!如果您想了解 CameraX 的最新進展,請加入 Android CameraX 討論組

更多資訊

歡迎您 點選這裡 向我們提交反饋,或分享您喜歡的內容、發現的問題。您的反饋對我們非常重要,感謝您的支援!

相關文章