Posted by Scott Nien – Software program Engineer (scottnien@)
Get able to stage up your Android digital camera apps! CameraX 1.4.0 simply dropped with a load of superior new options and enhancements. We’re speaking expanded HDR capabilities, preview stabilization and the versatile impact framework, and a complete lot of cool stuff to discover. We can even discover the way to seamlessly combine CameraX with Jetpack Compose! Let’s dive in and see how these enhancements can take your digital camera app to the following stage.
HDR preview and Extremely HDR
Excessive Dynamic Vary (HDR) is a game-changer for images, capturing a wider vary of sunshine and element to create stunningly life like photographs. With CameraX 1.3.0, we introduced you HDR video recording capabilities, and now in 1.4.0, we’re taking it even additional! Prepare for HDR Preview and Extremely HDR. These thrilling additions empower you to ship a fair richer visible expertise to your customers.
HDR Preview
This new characteristic means that you can allow HDR on Preview without having to bind a VideoCapture use case. That is particularly helpful for apps that use a single preview stream for each exhibiting preview on show and video recording with an OpenGL pipeline.
To completely allow the HDR, it’s essential guarantee your OpenGL pipeline is able to processing the particular dynamic vary format after which test the digital camera functionality.
See following code snippet for example to allow HLG10 which is the baseline HDR normal that gadget makers should help on cameras with 10-bit output.
// Declare your OpenGL pipeline supported dynamic vary format. val openGLPipelineSupportedDynamicRange = setOf( DynamicRange.SDR, DynamicRange.HLG_10_BIT ) // Verify digital camera dynamic vary capabilities. val isHlg10Supported = cameraProvider.getCameraInfo(cameraSelector) .querySupportedDynamicRanges(openGLPipelineSupportedDynamicRange) .incorporates(DynamicRange.HLG_10_BIT) val preview = Preview.Builder().apply { if (isHlg10Supported) { setDynamicRange(DynamicRange.HLG_10_BIT) } }
Extremely HDR
Introducing Extremely HDR, a brand new format in Android 14 that lets customers seize stunningly life like images with unbelievable dynamic vary. And one of the best half? CameraX 1.4.0 makes it extremely straightforward so as to add Extremely HDR seize to your app with only a few strains of code:
val cameraSelector = CameraSelector.DEFAULT_BACK_CAMERA val cameraInfo = cameraProvider.getCameraInfo(cameraSelector) val isUltraHdrSupported = ImageCapture.getImageCaptureCapabilities(cameraInfo) .supportedOutputFormats .incorporates(ImageCapture.OUTPUT_FORMAT_JPEG_ULTRA_HDR) val imageCapture = ImageCapture.Builder().apply { if (isUltraHdrSupported) { setOutputFormat(ImageCapture.OUTPUT_FORMAT_JPEG_ULTRA_HDR) } }.construct()
Jetpack Compose help
Whereas this put up focuses on 1.4.0, we’re excited to announce the Jetpack Compose help in CameraX 1.5.0 alpha. We’re including help for a Composable Viewfinder constructed on high of AndroidExternalSurface and AndroidEmbeddedExternalSurface. The CameraXViewfinder Composable hooks up a show floor to a CameraX Preview use case, dealing with the complexities of rotation, scaling and Floor lifecycle so that you don’t have to.
// in construct.gradle implementation ("androidx.digital camera:camera-compose:1.5.0-alpha03") class PreviewViewModel : ViewModel() { non-public val _surfaceRequests = MutableStateFlow(null) val surfaceRequests: StateFlow get() = _surfaceRequests.asStateFlow() non-public enjoyable produceSurfaceRequests(previewUseCase: Preview) { // All the time publish new SurfaceRequests from Preview previewUseCase.setSurfaceProvider { newSurfaceRequest -> _surfaceRequests.worth = newSurfaceRequest } } // ... } @Composable enjoyable MyCameraViewfinder( viewModel: PreviewViewModel, modifier: Modifier = Modifier ) { val currentSurfaceRequest: SurfaceRequest? by viewModel.surfaceRequests.collectAsState() currentSurfaceRequest?.let { surfaceRequest -> CameraXViewfinder( surfaceRequest = surfaceRequest, implementationMode = ImplementationMode.EXTERNAL, // Or EMBEDDED modifier = modifier ) } }
Kotlin-friendly APIs
CameraX is getting much more Kotlin-friendly! In 1.4.0, we have launched two new droop capabilities to streamline digital camera initialization and picture seize.
// CameraX initialization val cameraProvider = ProcessCameraProvider.awaitInstance() val imageProxy = imageCapture.takePicture() // Processing imageProxy imageProxy.shut()
Preview Stabilization and Mirror mode
Preview Stabilization
Preview stabilization mode was added in Android 13 to allow the stabilization on all non-RAW streams, together with previews and MediaCodec enter surfaces. In comparison with the earlier video stabilization mode, which can have inconsistent FoV (Area of View) between the preview and recorded video, this new preview stabilization mode ensures consistency and thus offers a greater consumer expertise. For apps that document the preview immediately for video recording, this mode can also be the one strategy to allow stabilization.
Observe the code beneath to allow preview stabilization. Please observe that when preview stabilization is turned on, it’s not solely utilized to the Preview but in addition to the VideoCapture whether it is sure as properly.
val isPreviewStabilizationSupported = Preview.getPreviewCapabilities(cameraProvider.getCameraInfo(cameraSelector)) .isStabilizationSupported val preview = Preview.Builder().apply { if (isPreviewStabilizationSupported) { setPreviewStabilizationEnabled(true) } }.construct()
MirrorMode
Whereas CameraX 1.3.0 launched mirror mode for VideoCapture, we have now introduced this helpful characteristic to Preview in 1.4.0. That is particularly helpful for gadgets with outer shows, permitting you to create a extra pure selfie expertise when utilizing the rear digital camera.
To allow the mirror mode, merely name Preview.Builder.setMirrorMode APIs. This characteristic is supported for Android 13 and above.
Actual-time Impact
CameraX 1.3.0 launched the CameraEffect framework, providing you with the facility to customise your digital camera output with OpenGL. Now, in 1.4.0, we’re taking it a step additional. Along with making use of your personal customized results, now you can leverage a set of pre-built results supplied by CameraX and Media3, making it simpler than ever to reinforce your app’s digital camera options.
Overlay Impact
The brand new camera-effects artifact goals to supply ready-to-use impact implementations, beginning with the OverlayEffect. This impact enables you to draw overlays on high of digital camera frames utilizing the acquainted Canvas API.
The next pattern code reveals the way to detect the QR code and draw the form of the QR code as soon as it’s detected.
By default, drawing is carried out in floor body coordinates. However what if it’s essential use digital camera sensor coordinates? No downside! OverlayEffect offers the Body#getSensorToBufferTransform perform, permitting you to use the mandatory transformation matrix to your overlayCanvas.
On this instance, we use CameraX’s MLKit Imaginative and prescient APIs (MlKitAnalyzer) and specify COORDINATE_SYSTEM_SENSOR to acquire QR code nook factors in sensor coordinates. This ensures correct overlay placement no matter gadget orientation or display screen side ratio.
// in construct.gradle implementation ("androidx.digital camera:camera-effects:1.4.1}") implementation ("androidx.digital camera:camera-mlkit-vision:1.4.1") var qrcodePoints: Array? = null val qrcodeBoxEffect = OverlayEffect( PREVIEW /* utilized on the preview solely */, 0, /* queueDepth */, Handler(Looper.getMainLooper()), {} ) enjoyable initCamera() { qrcodeBoxEffect.setOnDrawListener { body -> body.overlayCanvas.drawColor(Coloration.TRANSPARENT, PorterDuff.Mode.CLEAR) qrcodePoints?.let { // Utilizing sensor coordinates to attract. body.overlayCanvas.setMatrix(body.sensorToBufferTransform) val path = android.graphics.Path().apply { it.forEachIndexed { index, level -> if (index == 0) { moveTo(level.x.toFloat(), level.y.toFloat()) } else { lineTo(level.x.toFloat(), level.y.toFloat()) } } lineTo(it[0].x.toFloat(), it[0].y.toFloat()) } body.overlayCanvas.drawPath(path, paint) } true } val imageAnalysis = ImageAnalysis.Builder() .construct() .apply { setAnalyzer(executor, MlKitAnalyzer( listOf(barcodeScanner!!), COORDINATE_SYSTEM_SENSOR, executor ) { consequence -> val barcodes = consequence.getValue(barcodeScanner!!) qrcodePoints = barcodes?.takeIf { it.dimension > 0}?.get(0)?.cornerPoints } ) } val useCaseGroup = UseCaseGroup.Builder() .addUseCase(preview) .addUseCase(imageAnalysis) .addEffect(qrcodeBoxEffect) .construct() cameraProvider.bindToLifecycle( lifecycleOwner, cameraSelector, usecaseGroup) }
Media3 Impact
Wish to add beautiful digital camera results to your CameraX app? Now you may faucet into the facility of Media3’s wealthy results framework! This thrilling integration means that you can apply Media3 results to your CameraX output, together with Preview, VideoCapture, and ImageCapture.
This implies you may simply improve your app with a variety of professional-grade results, from blurs and colour filters to transitions and extra. To get began, merely use the brand new androidx.digital camera:media3:media3-effect artifact.
Here is a fast instance of the way to apply a Gaussian blur to your digital camera output:
// in construct.gradle implementation ("androidx.digital camera.media3:media3-effect:1.0.0-alpha01") implementation ("androidx.media3:media3-effect:1.5.0") import androidx.digital camera.media3.impact.Media3Effect val media3Effect = Media3Effect( requireContext(), PREVIEW or VIDEO_CAPTURE or IMAGE_CAPTURE, mainThreadExecutor(), {} ) // use grayscale impact media3Effect.setEffects(listOf(RgbFilter.createGrayscaleFilter()) cameraController.setEffects(setOf(media3Effect)) // or utilizing UseCaseGroup API
Here’s what the impact seems like:
Display screen Flash
Taking selfies in low mild simply bought simpler with CameraX 1.4.0! This launch introduces a strong new characteristic: display screen flash. As a substitute of counting on a conventional LED flash which most selfie cameras don’t have, display screen flash cleverly makes use of your telephone’s show. By momentarily turning the display screen brilliant white, it offers a burst of illumination that helps seize clear and vibrant selfies even in difficult lighting circumstances.
Integrating display screen flash into your CameraX app is versatile and simple. You may have two important choices:
1. Implement the ScreenFlash interface: This offers you full management over the display screen flash habits. You’ll be able to customise the colour, depth, period, and another side of the flash. That is superb if you happen to want a extremely tailor-made resolution.
2. Use the built-in implementation: For a fast and straightforward resolution, leverage the pre-built display screen flash performance in ScreenFlashView or PreviewView. This implementation handles all of the heavy lifting for you.
In the event you’re already utilizing PreviewView in your app, enabling display screen flash is extremely easy. Simply allow it immediately on the PreviewView occasion. In the event you want extra management or aren’t utilizing PreviewView, you need to use ScreenFlashView immediately.
Here is a code instance demonstrating the way to allow display screen flash:
// case 1: PreviewView + CameraX core API. previewView.setScreenFlashWindow(exercise.getWindow()); imageCapture.screenFlash = previewView.screenFlash imageCapture.setFlashMode(ImageCapture.FLASH_MODE_SCREEN) // case 2: PreviewView + CameraController previewView.setScreenFlashWindow(exercise.getWindow()); cameraController.setImageCaptureFlashMode(ImageCapture.FLASH_MODE_SCREEN); // case 3 : use ScreenFlashView screenFlashView.setScreenFlashWindow(exercise.getWindow()); imageCapture.setScreenFlash(screenFlashView.getScreenFlash()); imageCapture.setFlashMode(ImageCapture.FLASH_MODE_SCREEN);
Digicam Extensions new options
Digicam Extensions APIs intention to assist apps to entry the cutting-edge capabilities beforehand accessible solely on built-in digital camera apps. And the ecosystem is rising quickly! In 2024, we have seen main gamers like Pixel, Samsung, Xiaomi, Oppo, OnePlus, Vivo, and Honor all embrace Digicam Extensions, significantly for Evening Mode and Bokeh Mode. CameraX 1.4.0 takes this even additional by including help for brand-new Android 15 Digicam Extensions options, together with:
- Postview: Gives a preview of the captured picture virtually immediately earlier than the long-exposure photographs are accomplished
- Seize Course of Progress: Shows a progress indicator so customers understand how lengthy capturing and processing will take, bettering the expertise for options like Evening Mode
- Extensions Energy: Permits customers to fine-tune the depth of the utilized impact
Beneath is an instance of the improved UX that makes use of postview and seize course of progress options on Samsung S24 Extremely.
to understand how this may be applied? See the pattern code beneath:
val extensionsCameraSelector = extensionsManager .getExtensionEnabledCameraSelector(DEFAULT_BACK_CAMERA, extensionMode) val isPostviewSupported = ImageCapture.getImageCaptureCapabilities( cameraProvider.getCameraInfo(extensionsCameraSelector) ).isPostviewSupported val imageCapture = ImageCapture.Builder().apply { setPostviewEnabled(isPostviewSupported) }.construct() imageCapture.takePicture(outputfileOptions, executor, object : OnImageSavedCallback { override enjoyable onImageSaved(outputFileResults: OutputFileResults) { // ultimate picture saved. } override enjoyable onPostviewBitmapAvailable(bitmap: Bitmap) { // Postview bitmap is out there. } override enjoyable onCaptureProcessProgressed(progress: Int) { // seize course of progress replace } }
Essential: In case your app bumped into the CameraX Extensions challenge on Pixel 9 sequence gadgets, please use CameraX 1.4.1 as an alternative. This launch fixes a vital challenge that prevented Evening Mode from working accurately with takePicture.
What’s Subsequent
We hope you take pleasure in this new launch. Our mission is to make digital camera improvement a pleasure, eradicating the friction and ache factors so you may give attention to innovation. With CameraX, you may simply harness the facility of Android’s digital camera capabilities and construct really superb app experiences.
Have questions or wish to join with the CameraX workforce? Be part of the CameraX developer dialogue group or file a bug report:
We are able to’t wait to see what you create!