Files

4.5 KiB

This guide covers implementing low-light features using Night mode extensions and Low Light Boost (LLB).

Choosing the right tool

Feature Used for Implementation UX impact
Night mode High-quality stills ExtensionsManager Possibly requires user to hold still for several seconds.
LLB, AE mode Real-time preview or video Camera2Interop, CameraX utility Hardware drops the frame rate to increase brightness.
LLB, Play services Real-time preview and video SurfaceProcessor Software-based brightening; maintains a higher frame rate.

Night mode extension

CameraX Extensions provide access to the device's built-in computational photography pipeline.

Basic setup

To set up the extension, initialize the extension manager:

// Use ListenableFuture.await() extension function for coroutine support
val extensionsManager = ExtensionsManager.getInstanceAsync(context, cameraProvider).await()
if (extensionsManager.isExtensionAvailable(cameraSelector, ExtensionMode.NIGHT)) {
    val nightSelector = extensionsManager.getExtensionEnabledCameraSelector(
        cameraSelector, ExtensionMode.NIGHT
    )
    cameraProvider.bindToLifecycle(lifecycleOwner, nightSelector, imageCapture, preview)
}

Comprehensive features

  • Image postview : Display a low-resolution image immediately while the multi-frame processing occurs.

    val imageCapture = ImageCapture.Builder()
        .setPostviewEnabled(true)
        .build()
    
  • Extension strength : Let users control the intensity of the night effect.

    // Set the strength of the active extension (e.g. NIGHT mode intensity)
    val extensionsManager = ExtensionsManager.getInstanceAsync(context, cameraProvider).await()
    val extensionsControl = extensionsManager.getCameraExtensionsControl(camera.cameraControl)
    extensionsControl?.setExtensionStrength(strength)
    
  • Capture progress : Show a UI progress bar for long exposures.

    // Use the suspend extension function for takePicture to avoid callback boilerplate
    try {
        val result = imageCapture.takePicture(outputOptions)
        // Use result.savedUri or other fields
    } catch (e: ImageCaptureException) {
        // Handle capture failure
    }
    

Low-light boost

LLB is designed for preview and video streams where you prefer high frame rates.

AE mode

The built-in CameraX way to prioritize brightness. It modifies the hardware's auto-exposure algorithm.

  • Activation : Use CameraControl.enableLowLightBoostAsync.

  • Implementation :

    // Enable Low Light Boost (LLB) natively in CameraX 1.4+
    camera.cameraControl.enableLowLightBoostAsync(true)
    
  • Monitoring : Observe CameraInfo.lowLightBoostState to track when the hardware actively applies the enhancement.

Google Play services LLB

It's a multi-step implementation that uses a session-based SurfaceProcessor.

Dependency : com.google.android.gms:play-services-camera-low-light-boost

To implement Google Play services LLB, follow these core steps:

  1. Initialize client : val client = LowLightBoost.getClient.

  2. Implement SurfaceProcessor :

    • Manage session : Call client.createSession.
    • Forward required metadata : Observe the camera's TotalCaptureResult stream and forward every result to the session: session.processCaptureResult.
    • Provide surface : Get the input surface from the session, session.getCameraSurface, and provide it to the camera's SurfaceRequest.
    • Lifecycle : Release the session, session.release, when the processor is closed or the SurfaceRequest completes.
  3. Wire using CameraEffect :

    val effect = SimpleCameraEffect(
        CameraEffect.PREVIEW or CameraEffect.VIDEO_CAPTURE,
        executor,
        llbSurfaceProcessor
    ) { throw it }
    
    // Add to UseCaseGroup
    val useCaseGroup = UseCaseGroup.Builder()
        .addUseCase(preview)
        .addUseCase(videoCapture)
        .addEffect(effect)
        .build()
    
  4. Scene detection : Use session.setSceneDetectorCallback to receive boostStrength updates for real-time UI indicators.


Implementation notes

  • Thread safety : Always handle ExtensionsManager and LowLightBoostClient initialization asynchronously.
  • FPS trade-offs: AE mode LLB often drops the frame rate significantly to increase brightness.
  • Compatibility : Extensions, Night Mode, possibly conflict with ConcurrentCamera. Always verify support before binding.