我們最近分享了 Instagram 如何讓使用者透過夜間模式拍出令人驚豔的低光源相片。這項功能非常適合靜態影像,因為有時間結合多重曝光,建立高品質的靜態相片。但如果想記錄相片之間的精彩時刻,該怎麼辦?使用者與相機的互動不應僅限於按下快門按鈕。此外,他們也會使用預覽畫面來構圖或掃描 QR code。
今天,我們要深入探討低光源強化 (LLB),這項強大功能可提高即時攝影機串流影像的亮度。與夜間模式不同,低光源強化功能會立即在即時預覽和影片錄製中生效,不需等待拍攝完成。LLB 會根據可用光線自動調整亮度,因此在任何環境下都能呈現最佳效果。
在最近一次更新中,LLB 讓 Instagram 使用者能拍出完美相片,而現有的夜間模式實作則能產生相同的高畫質低光源相片,讓使用者一年多來都能享受這項功能。
即時亮度為何重要
夜間模式旨在提升最終影像品質,而低光源強化功能則著重於黑暗環境中的可用性和互動性。另一個需要考量的重要因素是,雖然低光源模式和夜間模式可以搭配使用,但也可以單獨使用。在某些用途中,即使不需要夜間模式相片,低光源模式本身也很有價值。LLB 提升使用者體驗的方式如下:
- 更出色的取景和拍攝效果:在昏暗場景中,標準相機預覽畫面可能會一片漆黑。LLB 會調亮觀景窗,讓使用者在按下快門按鈕前,能實際看到取景畫面。在這種情況下,你可以使用夜間模式,在低光源環境下拍出最佳相片,也可以讓 LLB 為使用者提供「所見即所得」的相片。
- 可靠的掃描功能:QR code 隨處可見,但在昏暗的餐廳或室內停車場掃描時,往往會遇到困難。攝影機畫面亮度大幅提升後,即使在非常昏暗的環境中,掃描演算法也能可靠地偵測及解碼 QR code。
- 強化互動:對於涉及即時影像互動的應用程式 (例如 AI 助理或視訊通話),LLB 可增加可感知資訊量,確保電腦視覺模型有足夠的資料可供使用
Instagram 的差異
Android 版 Instagram 應用程式的工程團隊一直努力不懈,致力為使用者提供最先進的相機體驗。從上方的範例中,你可以看到 LLB 在 Pixel 10 Pro 上帶來的差異。
不難想像這對使用者體驗造成的影響。如果使用者無法看到自己擷取的內容,就更有可能放棄擷取。
選擇導入方式
您可以透過兩種方式導入低光源強化功能,在各種裝置上提供最佳體驗:
- 低光源增強 AE 模式:這是硬體層自動曝光模式。這項功能會直接微調影像訊號處理器 (ISP) 管道,因此能提供最高品質和效能。請務必先檢查這一點。
- Google 低光源提升:如果裝置不支援 AE 模式,可以改用 Google Play 服務提供的軟體解決方案。這項功能會對攝影機串流影像進行後置處理,提高亮度。由於這項解決方案完全採用軟體,因此適用於更多裝置,可協助您觸及更多支援 LLB 的裝置。
低光源增強 AE 模式 (硬體)
機制:
搭載 Android 15 以上版本的裝置支援此模式,且原始設備製造商 (OEM) 必須在 HAL 中實作支援 (目前適用於 Pixel 10 裝置)。直接與相機的影像訊號處理器 (ISP) 整合。如果將 CaptureRequest.CONTROL_AE_MODE 設為 CameraMetadata.CONTROL_AE_MODE_ON_LOW_LIGHT_BOOST_BRIGHTNESS_PRIORITY,相機系統就會接管控制權。
行為:
HAL/ISP 會分析場景並調整感應器和處理參數 (通常包括增加曝光時間),以提高圖片亮度。這樣一來,由於曝光時間延長,感應器可以擷取更多光線資訊,而不是增加數位感應器增益 (ISO),因此可以大幅提高訊噪比 (SNR)。
優點:
利用專屬硬體路徑,可能提升影像品質和能源效率。
缺點:
在極暗環境下,感應器需要更多時間捕捉光線,因此影格率可能會降低。在極低光源環境下,影格率最低可降至 10 FPS。
Google 低光源增強 (透過 Google Play 服務提供的軟體)
機制:
這項解決方案會透過 Google Play 服務以選用模組的形式發布,並對攝影機串流影像套用後置處理。這項功能採用名為 HDRNet 的精密即時影像強化技術。
Google HDRNet:
這個深度學習模型會分析低解析度的圖片,預測一組精簡的參數 (雙邊網格)。接著,這個網格會引導 GPU 對全解析度圖片進行高效、空間變化的強化。這個模型經過訓練,可在低光源環境下調亮及提升影像品質,並著重於臉部清晰度。
程序自動化調度管理:
HDRNet 模型和隨附邏輯由低光源增強處理器自動調度管理。包括:
- 場景分析:
自訂計算工具,可使用相機中繼資料 (感應器感光度、曝光時間等) 和圖片內容,估算真實場景亮度。這項分析會決定提升等級。 - HDRNet 處理:
套用 HDRNet 模型,提高影格亮度。使用的模型經過調整,適用於低光源場景,並針對即時效能進行最佳化。 - 混合:
混合原始和 HDRNet 處理過的影格。場景亮度計算工具會動態控制混合程度,確保增強和未增強狀態之間的轉換流暢。
優點:
支援更多裝置 (目前支援 Samsung S22 Ultra、S23 Ultra、S24 Ultra、S25 Ultra,以及 Pixel 6 至 Pixel 9),不需特定 HAL 支援。由於這是後製效果,因此可維持相機的影格率。
缺點:
由於這是後製處理方法,品質會受限於感應器傳送的影格資訊。如果感應器偵測到極度黑暗,就無法復原遺失的細節。
低光源強化功能提供硬體和軟體兩種途徑,可做為可擴充的解決方案,提升整個 Android 生態系統的低光源相機效能。開發人員應優先使用 AE 模式 (如有),並將 Google 低光源強化功能做為可靠的備用方案。
在應用程式中導入低光源增強功能
接著,我們來看看如何導入這兩種 LLB 方案。無論您在應用程式中使用 CameraX 或 Camera2,都可以實作下列步驟。為獲得最佳效果,建議您同時實作步驟 1 和步驟 2。
步驟 1:低光源增強 AE 模式
LLB AE 模式適用於搭載 Android 15 以上版本的特定裝置,是一種特定的自動曝光 (AE) 模式。
1. 檢查供應情形
首先,請確認相機裝置是否支援 LLB AE 模式。
val cameraInfo = cameraProvider.getCameraInfo(cameraSelector) val isLlbSupported = cameraInfo.isLowLightBoostSupported
2. 啟用模式
如果支援,您可以使用 CameraX 的 CameraControl 物件啟用 LLB AE 模式。
// After setting up your camera, use the CameraInfo object to enable LLB AE Mode.
camera = cameraProvider.bindToLifecycle(...)
if (isLlbSupported) {
try {
// The .await() extension suspends the coroutine until the
// ListenableFuture completes. If the operation fails, it throws
// an exception which we catch below.
camera?.cameraControl.enableLowLightBoostAsync(true).await()
} catch (e: IllegalStateException) {
Log.e(TAG, "Failed to enable low light boost: not available on this device or with the current camera configuration", e)
} catch (e: CameraControl.OperationCanceledException) {
Log.e(TAG, "Failed to enable low light boost: camera is closed or value has changed", e)
}
}3. 監控狀態
即使你要求啟用這個模式,也不代表系統目前正在「加速」。只有在場景確實昏暗時,系統才會啟用增強功能。您可以設定 Observer 來更新 UI (例如顯示月亮圖示),或使用擴充功能函式 asFlow() 轉換為 Flow。
if (isLlbSupported) {
camera?.cameraInfo.lowLightBoostState.asFlow().collectLatest { state ->
// Update UI accordingly
updateMoonIcon(state == LowLightBoostState.ACTIVE)
}
}如需低光源強化自動曝光模式的完整指南,請參閱 這篇文章。
步驟 2:Google 低光源增強
如果裝置不支援硬體 AE 模式,Google 低光源增強功能可做為強大的備用方案。它會使用 LowLightBoostSession 攔截並調亮串流。
1. 新增依附元件
這項功能是透過 Google Play 服務提供。
implementation("com.google.android.gms:play-services-camera-low-light-boost:16.0.1-beta06")
// Add coroutines-play-services to simplify Task APIs
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-play-services:1.10.2")2. 初始化用戶端
啟動相機前,請使用 LowLightBoostClient 確認模組已安裝,且裝置支援該模組。
val llbClient = LowLightBoost.getClient(context)
// Check support and install if necessary
val isSupported = llbClient.isCameraSupported(cameraId).await()
val isInstalled = llbClient.isModuleInstalled().await()
if (isSupported && !isInstalled) {
// Trigger installation
llbClient.installModule(installCallback).await()
}3. 建立 LLB 工作階段
Google LLB 會處理每個影格,因此您必須將顯示介面提供給 LowLightBoostSession,系統會傳回已套用亮度調整的介面。如果是 Camera2 應用程式,您可以使用 CaptureRequest.Builder.addTarget() 新增產生的 Surface。如果是 CameraX,這個處理管道最適合與 CameraEffect 類別搭配使用,您可以使用 SurfaceProcessor 套用效果,並使用 SurfaceProvider 將效果提供給預覽畫面,如這段程式碼所示。
// With a SurfaceOutput from SurfaceProcessor.onSurfaceOutput() and a
// SurfaceRequest from Preview.SurfaceProvider.onSurfaceRequested(),
// create a LLB Session.
suspend fun createLlbSession(surfaceRequest: SurfaceRequest, outputSurfaceForLlb: Surface) {
// 1. Create the LLB Session configuration
val options = LowLightBoostOptions(
outputSurfaceForLlb,
cameraId,
surfaceRequest.resolution.width,
surfaceRequest.resolution.height,
true // Start enabled
)
// 2. Create the session.
val llbSession = llbClient.createSession(options, callback).await()
// 3. Get the surface to use.
val llbInputSurface = llbSession.getCameraSurface()
// 4. Provide the surface to the CameraX Preview UseCase.
surfaceRequest.provideSurface(llbInputSurface, executor, resultListener)
// 5. Set the scene detector callback to monitor how much boost is being applied.
val onSceneBrightnessChanged = object : SceneDetectorCallback {
override fun onSceneBrightnessChanged(
session: LowLightBoostSession,
boostStrength: Float
) {
// Monitor the boostStrength from 0 (no boosting) to 1 (maximum boosting)
}
}
llbSession.setSceneDetectorCallback(onSceneBrightnessChanged, null)
}4. 傳入中繼資料
演算法必須分析相機的自動曝光狀態,才能正常運作。您必須將擷取結果傳回 LLB 工作階段。在 CameraX 中,您可以使用 Camera2Interop.Extender.setSessionCaptureCallback() 擴充 Preview.Builder,藉此完成這項操作。
Camera2Interop.Extender(previewBuilder).setSessionCaptureCallback(
object : CameraCaptureSession.CaptureCallback() {
override fun onCaptureCompleted(
session: CameraCaptureSession,
request: CaptureRequest,
result: TotalCaptureResult
) {
super.onCaptureCompleted(session, request, result)
llbSession?.processCaptureResult(result)
}
}
)如需用戶端和工作階段的詳細實作步驟,請參閱 Google 低光源強化指南。
後續步驟
只要實作這兩種選項,無論光線條件如何,使用者都能清楚看見、可靠掃描,並有效互動。
如要查看這些功能在可部署於正式環境的完整程式碼集中如何運作,請前往 GitHub 參閱 Jetpack Camera 應用程式。這個範例會實作 LLB AE 模式和 Google LLB,可做為您整合時的參考。
-
產品最新消息隨著代理式開發加速發展,Android 工程技術也邁入令人期待的新境界:從輔助程式碼補全,到代理依據您的指示執行端對端作業。您可以自由選擇要使用的模型和代理,享有充分彈性。
Jason Buchel • 閱讀時間:3 分鐘 -
產品最新消息今天,我們分享了如何將「不只是商店」的願景推向新階段。Google Play 致力於滿足使用者需求,包括推出「個人中心」分頁,成為每月超過 2.5 億活躍使用者的個人中心,以及整合遊戲平台,連結超過 7 億個玩家個人資料。
Paul Feng • 閱讀時間:3 分鐘 -
產品最新消息我們很高興能透過 Googlebook 協助使用者表達自我,並取得這些工具。
Cyrus Stoller • 閱讀時間:2 分鐘
每週透過電子郵件接收最新的 Android 開發洞察資訊。