我們最近 分享了 Instagram 如何讓使用者透過夜間模式,在低光源環境中拍出絕美相片。這項功能非常適合靜態圖片,因為有時間合併多種曝光度,製作出高品質的靜態相片。但相片之間的時刻呢?使用者與相機的互動不只是按下快門按鈕的瞬間,他們也可以使用預覽畫面構圖或掃描 QR code。
今天,我們要深入瞭解低光源增強 (LLB),這項強大功能可調亮即時攝影機串流。低光源強化功能與夜間模式不同,不需要固定拍攝一段時間,而是會即時套用至即時預覽畫面和影片錄製內容。LLB 會根據可用光線自動調整所需亮度,因此適用於各種環境。
最近的更新讓 Instagram 使用者可以拍出完美畫面,而現有的 LLB 夜間模式實作方式,可讓使用者拍出與過去一年來一樣高品質的低光源相片。
即時亮度為何重要
夜間模式的目標是提升最終影像品質,低光源強化功能則著重於在昏暗環境中的可用性和互動性。另一個重要因素是,即使 LLB 和夜間模式搭配使用效果極佳,你也可以單獨使用 LLB 和夜間模式。在某些使用情況下,即使不需要夜間模式相片,LLB 也能發揮價值。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 支援。維持攝影機的影格率,因為這是後製效果。
取捨:
做為後續處理方法,品質會受到感應器傳送的畫面資訊限制。如果感應器層級的極度昏暗環境導致細節遺失,則無法復原。
Low Light Boost 提供軟硬體路徑,是可擴充的解決方案,可提升 Android 生態系統的低光源相機效能。開發人員應盡可能優先使用 AE 模式,並將 Google 低光源增強功能做為可靠的備用選項。
在應用程式中導入低光源增強功能
接著來看看如何導入這兩種 LLB 產品。無論您在應用程式中使用 CameraX 或 Camera2,都可以實作下列步驟。為獲得最佳成效,建議您同時實作步驟 1 和步驟 2。
步驟 1:低光源增強自動曝光模式
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)
}
}
如要閱讀低光源增強 AE 模式的完整指南,請參閱 這篇文章。
步驟 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 會處理每個影格,因此您必須將螢幕 Surface 提供給 LowLightBoostSession,而該函式會傳回套用亮度調整的 Surface。如果是 Camera2 應用程式,可以使用 CaptureRequest.Builder.addTarget() 新增產生的 Surface。如果是 CameraX,這個處理管道最適合 CameraEffect 類別,您可以使用 SurfaceProcessor 套用效果,並透過 SurfaceProvider 將效果提供給 Preview,如這段程式碼所示。
// 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 App。這個範例會實作 LLB AE 模式和 Google LLB,可做為您自行整合的參考。
繼續閱讀
-
產品新訊
盡可能確保 Google Play 提供最安全可靠的服務體驗。今天,我們宣布推出一系列新政策和帳戶轉移功能,進一步保障使用者隱私,並防範詐欺行為。
Bennet Manuel • 3 分鐘可讀完
-
產品新訊
現在使用 Android Emulator,就能輕鬆測試支援多種裝置的互動。
Steven Jenkins • 閱讀時間:2 分鐘
-
產品新訊
每位開發人員的 AI 工作流程和需求都不盡相同,因此選擇 AI 輔助開發的方式非常重要。我們在 1 月推出這項功能,讓您選擇任何本機或遠端 AI 模型,為 Android Studio 中的 AI 功能提供支援
Matthew Warner • 閱讀時間:2 分鐘
隨時掌握最新消息
每週透過電子郵件接收最新的 Android 開發洞察資料。