CameraX is an Android Jetpack library for working with the camera, providing a simple and consistent API on top of the complex Camera2. It abstracts differences between hundreds of Android device models and ensures consistent camera behavior across different hardware. According to the Android Developer CameraX Guide (2026), the library is used in 25,000+ Google Play apps and works on devices with API Level 21 and above.
Key Takeaways
CameraX is a library from the Android Jetpack suite, first released by Google in 2019 as a replacement for the deprecated Camera API and a simplified alternative to the complex Camera2. The core philosophy of CameraX is “write once, run on all devices.” The library automatically handles hardware differences: camera placement, supported resolutions, sensor orientation, and available formats — the developer does not need to write device-specific code.
The CameraX architecture is built on use cases: Preview (displaying camera feed in Viewfinder), ImageCapture (taking photos), ImageAnalysis (analyzing frame stream for ML) and VideoCapture (recording video). Each use case is an independent component that can be combined: running Preview for the viewfinder and ImageAnalysis for ML processing simultaneously. According to Google (2026), CameraX is supported on 99% of Android devices with API 21+.
CameraX provides automatic switching between front and rear cameras, support for screen rotation without recreating the session, built-in lifecycle handling via LifecycleOwner, binding use cases to a single Lifecycle process, support for Camera2 Extensions for portrait, HDR and night mode, and TestableCameraX for unit testing without a real device.
CameraX defines four standard use cases, each solving a specific camera task. Use cases can be combined: the most popular combinations are Preview + ImageCapture for a camera app and Preview + ImageAnalysis for an ML scanner.
| Use Case | Purpose | Class |
|---|---|---|
| Preview | Displaying real-time camera feed | PreviewView |
| ImageCapture | Taking photos with flash and resolution settings | ImageCapture |
| ImageAnalysis | Analyzing each frame for ML processing | ImageAnalysis |
| VideoCapture | Recording video with microphone (since 1.1.0-beta) | VideoCapture |
Preview use case displays the camera video stream in PreviewView — a special View from the CameraX library. PreviewView automatically adapts to the camera aspect ratio, supports ScaleType (FillCenter, FitCenter) and screen rotation without recreating the use case. The developer only needs to bind the Preview to a Lifecycle via ProcessCameraProvider.
ImageAnalysis use case sends each camera frame to a handler for analysis: text recognition, face detection, QR code scanning. The analyzer receives frames in YUV_420_888 format — the universal Android color space. Operating mode (BLOCKING or NON_BLOCKING) controls the frame queue: BLOCKING waits for the previous analysis to complete, NON_BLOCKING skips frames during delays.
ImageCapture use case takes photos from the camera with flash, resolution and compression settings. JPEG and RAW formats are supported (on compatible devices). ImageCapture saves the snapshot asynchronously via OnImageCapturedCallback or directly to a file via ImageCapture.OutputFileOptions.
VideoCapture use case was added in CameraX 1.1.0 (beta) and allows recording video at up to 4K at 30 FPS. The use case automatically synchronizes with Preview: the image in the viewfinder matches what is being recorded to the file. VideoCapture uses MediaCodec and MediaMuxer internally, hiding the complexity of configuring the video codec and MP4 container.
CameraX and Camera2 are two approaches to working with the camera in Android. Camera2 is a low-level API providing full control over the device. CameraX is a high-level abstraction automating typical scenarios. The choice between them depends on project requirements.
| Characteristic | CameraX | Camera2 |
|---|---|---|
| API Level | High (use case) | Low (full control) |
| Device-specific Code | Not required | Required for each device |
| Lifecycle Binding | Automatic | Manual |
| Extensions | Built-in (HDR, Portrait, Night) | Require OEM implementation |
| Implementation Complexity | 15–30 lines of code | 100–300 lines of code |
| API Support | API 21+ | API 21+ |
| Flexibility | Standard scenarios | Any scenarios |
Use CameraX for standard tasks: in-app camera, QR scanner, ML stream processing. Use Camera2 when manual exposure control, RAW shooting with full parameter control, or working with multiple cameras simultaneously is required.
Let’s review a full CameraX setup in an Android application using all three main use cases: Preview, ImageCapture and ImageAnalysis.
The code binds CameraX to the Activity Lifecycle via ProcessCameraProvider. First, a provider instance is requested, then use cases are created and binding is performed.
val cameraProviderFuture =
ProcessCameraProvider.getInstance(this)
cameraProviderFuture.addListener({
val cameraProvider = cameraProviderFuture.get()
// Creating Preview
val preview = Preview.Builder()
.build()
.also {
it.setSurfaceProvider(
binding.viewFinder.surfaceProvider
)
}
// Creating ImageCapture
val imageCapture = ImageCapture.Builder()
.setCaptureMode(ImageCapture.CAPTURE_MODE_MINIMIZE_LATENCY)
.build()
// Binding to Lifecycle
cameraProvider.unbindAll()
cameraProvider.bindToLifecycle(
this,
CameraSelector.DEFAULT_BACK_CAMERA,
preview,
imageCapture
)
}, ContextCompact.getMainExecutor(this))
The Kotlin code obtains ProcessCameraProvider via a future, creates Preview and ImageCapture use cases, and binds them to the current Activity Lifecycle. CameraX automatically handles screen rotation, camera switching and resource release when the Activity is closed.
Let’s add an ImageAnalysis use case for per-frame processing of the camera stream, for example to integrate with ML Kit.
val imageAnalysis = ImageAnalysis.Builder()
.setBackpressureStrategy(
ImageAnalysis.STRATEGY_KEEP_ONLY_LATEST
)
.build()
imageAnalysis.setAnalyzer(
ContextCompact.getMainExecutor(this)
) { imageProxy ->
// Converting YUV to Bitmap for ML Kit
val bitmap = ImageUtils.yuvToBitmap(imageProxy)
val inputImage = InputImage.fromBitmap(bitmap)
// Starting ML Kit text recognition
recognizer.process(inputImage)
.addOnSuccessListener { result ->
// Processing the result
processTextResult(result)
}
.addOnCompleteListener {
imageProxy.close()
}
}
ImageAnalysis with KEEP_ONLY_LATEST strategy processes only the latest available frame, skipping outdated ones if the analyzer is not keeping up. Each frame is converted from YUV to Bitmap for ML Kit, after which text recognition is launched. Calling imageProxy.close() is mandatory — otherwise CameraX will stop delivering new frames.
CameraX Extensions is a module that adds advanced shooting modes: portrait (background blur), HDR (extended dynamic range), night mode (low-light shooting), auto-retouch (skin correction) and beauty mode. Extensions are only activated on devices where the camera manufacturer has provided an OEM implementation.
Before using CameraX Extensions, you must check whether the extension is available on the current device. Google recommends checking via ExtensionsManager.isExtensionAvailable.
val extensionsManager =
ExtensionsManager.getInstance(this)
if (extensionsManager.isExtensionAvailable(
cameraProvider,
CameraSelector.DEFAULT_BACK_CAMERA,
ExtensionMode.BOKEH
)) {
// Enabling portrait mode
cameraProvider.bindToLifecycle(
this,
CameraSelector.DEFAULT_BACK_CAMERA,
preview,
imageCapture
)
}
The code checks support for the BOKEH (portrait) extension via ExtensionsManager and enables it if an OEM implementation is available. CameraX automatically switches camera settings for portrait mode. If the extension is not available, the app continues working in standard mode without crashes.
CameraX Extensions solve one of the main problems of Android development: camera fragmentation. On different devices, portrait mode is implemented differently — some use dual lenses, others use software blur. CameraX abstracts this difference: the developer enables BOKEH mode, and the library itself determines how to implement it on a specific device. Google maintains a list of verified OEM partners: Samsung, Xiaomi, OPPO, vivo, Google Pixel.
When working with CameraX, it is important to consider the limitations on the number of simultaneous use cases: on most devices, a maximum of 3 use cases can be run simultaneously. For example, Preview + ImageCapture + ImageAnalysis works on all modern devices, but Preview + ImageCapture + VideoCapture may not be supported on budget models. CameraX provides the ProcessCameraProvider.checkAvailability() method, which checks use case combination compatibility before binding, helping avoid runtime crashes.
CameraX integrates with Jetpack Navigation via CameraXFragment or Compose-compatible PreviewView. For Compose, the AndroidView element is used, into which PreviewView is embedded. CameraX correctly handles screen rotation and configuration changes without losing the camera session state — just specify the LifecycleOwner, and the library will automatically recreate use case bindings when the device rotates.
For testing CameraX without a real device, Google provides TestableCameraX — a library that emulates camera behavior in unit tests. TestableCameraX allows simulating camera frames, testing ImageAnalysis operation and ImageCapture correctness without a physical device. This significantly speeds up the CI/CD pipeline for projects working with the camera.
Frequently Asked Questions
Android 5.0 (API 21) and above. CameraX covers 99% of active Android devices. Extensions (Portrait, HDR) require API 23+ and OEM support for the specific mode.
Yes, the ImageAnalysis use case passes each frame to the analyzer. Frames are converted from YUV_420_888 to InputImage for ML Kit. This is the standard pattern for creating an ML scanner.
CameraX is a high-level API with use case architecture, automatic Lifecycle binding and handling of device-specific differences. Camera2 is a low-level API providing full camera control with a large amount of boilerplate code.
Yes, the VideoCapture use case was added in CameraX 1.1.0-beta. It records video with microphone and synchronizes with Preview. For more complex scenarios, use Camera2 directly.
Via CameraSelector: DEFAULT_BACK_CAMERA or DEFAULT_FRONT_CAMERA. To switch, call cameraProvider.bindToLifecycle() with a new selector — CameraX will automatically restart the session.
Summary
We will develop a mobile application turnkey
IT Sectr creates iOS and Android applications for startups and businesses since 2017. We will advise you and propose the best solution.
Read also