DEV Community

myougaTheAxo
myougaTheAxo

Posted on

CameraX Image Analysis: Custom Analyzers and ML Kit Integration

CameraX simplifies camera access. Learn custom analyzers, real-time ML Kit processing, and lifecycle management.

Add CameraX Dependency

implementation("androidx.camera:camera-core:1.3.0")
implementation("androidx.camera:camera-camera2:1.3.0")
implementation("androidx.camera:camera-lifecycle:1.3.0")
Enter fullscreen mode Exit fullscreen mode

Create Custom Analyzer

import androidx.camera.core.ImageAnalysis
import androidx.camera.core.ImageProxy

class BarcodeAnalyzer : ImageAnalysis.Analyzer {
    override fun analyze(imageProxy: ImageProxy) {
        val mediaImage = imageProxy.image
        if (mediaImage != null) {
            val image = InputImage.fromMediaImage(mediaImage, imageProxy.imageInfo.rotationDegrees)

            val barcodeScan = BarcodeScanning.getClient()
            barcodeScan.process(image)
                .addOnSuccessListener { barcodes ->
                    for (barcode in barcodes) {
                        processBarcode(barcode.rawValue ?: "")
                    }
                }
                .addOnCompleteListener {
                    imageProxy.close()
                }
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

Bind to Lifecycle

@Composable
fun CameraScreen(lifecycleOwner: LifecycleOwner = LocalLifecycleOwner.current) {
    val cameraProvider = ProcessCameraProvider.getInstance(LocalContext.current).await()

    val cameraSelector = CameraSelector.DEFAULT_BACK_CAMERA
    val imageAnalysis = ImageAnalysis.Builder()
        .setBackpressureStrategy(ImageAnalysis.STRATEGY_KEEP_ONLY_LATEST)
        .build()
        .apply {
            setAnalyzer(Executors.newSingleThreadExecutor(), BarcodeAnalyzer())
        }

    try {
        cameraProvider.unbindAll()
        cameraProvider.bindToLifecycle(
            lifecycleOwner,
            cameraSelector,
            imageAnalysis
        )
    } catch (e: Exception) {
        Log.e("CameraX", "Use case binding failed", e)
    }
}
Enter fullscreen mode Exit fullscreen mode

Performance Optimization

val imageAnalysis = ImageAnalysis.Builder()
    .setBackpressureStrategy(ImageAnalysis.STRATEGY_KEEP_ONLY_LATEST)  // Drop frames if slow
    .setOutputImageFormat(ImageAnalysis.OUTPUT_IMAGE_FORMAT_NV21)  // Smaller memory footprint
    .setTargetResolution(Size(480, 640))  // Lower resolution for faster analysis
    .build()
Enter fullscreen mode Exit fullscreen mode

CameraX abstracts Camera2 complexity. Use STRATEGY_KEEP_ONLY_LATEST for real-time analysis to prevent frame queuing. Always close ImageProxy to release buffers.


8 Android app templates (Habit Tracker, Budget Manager, Task Manager, and more) available on Gumroad

Top comments (0)