我们最近分享了 Instagram 如何让用户使用夜间模式拍摄出令人惊艳的弱光照片。此功能非常适合静态图片,因为有时间将多次曝光的照片组合起来,从而拍摄出高品质的静态照片。但照片之间的瞬间呢?用户需要与相机互动,而不仅仅是在按下快门按钮的那一刻。他们还可以使用预览功能来构图或扫描二维码。
今天,我们将深入探讨弱光增强 (LLB) 功能,这是一项旨在提亮实时相机视频流的强大功能。与需要保持静止拍摄一定时长的夜间模式不同,“弱光增强”功能可立即在实时预览和视频录制中发挥作用。LLB 会根据可用光线自动调整所需的提亮程度,因此可针对各种环境进行优化。
通过最近的一次更新,LLB 允许 Instagram 用户拍摄完美的照片,而其现有的夜间模式实现可让用户拍摄出与一年多以来一直享受的低光照照片一样的高质量照片。
实时亮度为何重要
夜间模式旨在提高最终图像质量,而弱光增强功能则旨在提高黑暗环境中的易用性和互动性。另一个需要考虑的重要因素是,尽管 LLB 和夜间模式可以很好地协同工作,但您也可以单独使用它们。在某些使用情形下,当不需要夜间模式照片时,您会发现 LLB 本身也很有价值。以下是 LLB 如何改善用户体验:
- 更好的取景和拍摄效果:在光线昏暗的场景中,标准相机预览画面可能会漆黑一片。LLB 会调亮取景器,让用户在按下快门按钮之前能够清楚地看到取景画面。对于这种体验,您可以使用夜间模式来获得最佳的低光照照片效果,也可以让 LLB 为用户提供“所见即所得”的照片效果。
- 可靠的扫描功能:二维码随处可见,但在昏暗的餐厅或停车场中扫描二维码往往令人沮丧。借助亮度明显更高的摄像头画面,扫描算法即使在非常昏暗的环境中也能可靠地检测和解码二维码。
- 增强互动:对于涉及实时视频互动的应用(例如 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 会分析场景并调整传感器和处理参数(通常包括增加曝光时间)以使图像变亮。这样可以生成信噪比 (SNR) 显著提高的帧,因为延长的曝光时间(而非增加数码传感器增益 [ISO])可让传感器捕获更多光线信息。
优势:
由于利用了专用硬件通道,因此可能具有更好的图像质量和能效。
权衡:
在非常昏暗的环境下,由于传感器需要更多时间来捕捉光线,因此可能会导致帧速率降低。在光线非常昏暗的条件下,帧速率可能会降至 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 来更新界面(例如显示月亮图标),也可以使用扩展函数 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 将其提供回预览,如以下代码所示。
// 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 相机应用。它实现了 LLB AE 模式和 Google LLB,可为您的集成提供参考。
-
产品资讯在 Google Play 上,我们一直在不断扩展订阅平台,以帮助您促进业务增长、适应新的业务模式,并满足用户的需求。
Sheenam Mittal • 阅读用时:4 分钟 -
产品资讯去年,Android Studio 开始支持任何 AI 模型。今天,我们将推出对您选择的编码智能体的支持,从而迈出下一步。
Matthew Warner • 阅读用时:3 分钟 -
产品资讯Googlebook 推出了一类基于共享 Android 基础构建的新型笔记本电脑。HP、Dell、Lenovo、Acer 和 Asus 等合作伙伴提供的高性能硬件,兼具移动便利性和桌面设备性能。
Fahd Imtiaz, Loryn Hairston • 阅读用时:4 分钟
每周通过电子邮件接收最新的 Android 开发洞见。