CameraX Use Cases

Preview, ImageCapture and ImageAnalysis Use Cases

A use case is one job for the camera: Preview feeds the viewfinder, ImageCapture takes photos, ImageAnalysis hands frames to your code (a barcode scanner, ML Kit), and VideoCapture records. Bound together to a LifecycleOwner, they open and close the camera with it. BookNest keeps them in a ViewModel:

camera/CameraScreen.kt: three use cases and one binding (excerpt)Kotlin
class CameraViewModel : ViewModel() {
  ...
  private val preview = Preview.Builder().build().apply {
    setSurfaceProvider { request -> _surfaceRequest.value = request }   // to the viewfinder
  }
  val capture: ImageCapture = ImageCapture.Builder()
    .setCaptureMode(ImageCapture.CAPTURE_MODE_MINIMIZE_LATENCY)
    .build()
  private val analysis = ImageAnalysis.Builder()
    .setBackpressureStrategy(ImageAnalysis.STRATEGY_KEEP_ONLY_LATEST)   // drop stale frames
    .build().apply {
      setAnalyzer(analysisExecutor) { image ->
        ...
        image.close()                                     // or no further frames arrive
      }
    }
  /** Binds while the caller's coroutine is active, unbinds when it is cancelled. */
  suspend fun bind(context: Context, owner: LifecycleOwner) {
    val provider = ProcessCameraProvider.awaitInstance(context)
    ...
    provider.unbindAll()
    provider.bindToLifecycle(owner, selector, preview, capture, analysis)
    try { awaitCancellation() } finally { provider.unbindAll() }
  }

The preview's surface requests go through a StateFlow to CameraXViewfinder(request, modifier), and a LaunchedEffect calls bind(). The analyzer averages the luminance (Y) plane every 60 frames; forgetting image.close() freezes analysis after one frame. It received 640x480 frames, the default:

Output of 174
D/BookNestCam( 6547): frame 640x480, rotation 90, brightness 230
D/BookNestCam( 6547): frame 640x480, rotation 90, brightness 202