CameraX is build, analyze() method is called and an image is passed and then closed (deleted) with close() method. From this image FirebaseVisionImage is created and passed for processing (text recognition). Code samples and code labs differs and not implement TextRecognition with CameraX or using old API versions.
override fun analyze(imageProxy: ImageProxy) {
if (isValidText) {
imageProxy.close()
return
}
val mediaImage = imageProxy.image // requires annotation
val degrees = imageProxy.imageInfo.rotationDegrees
val rotation = rotationDegreesToFirebaseRotation(degrees)
if (mediaImage != null) {
runTextRecognition(mediaImage, rotation) // line 44
}
imageProxy.close()
}
private fun runTextRecognition(mediaImage: Image, rotation: Int) {
// Create FirebaseVisionImage from frame
val visionImage = FirebaseVisionImage.fromMediaImage(mediaImage, rotation) // line 64
val recognizer = FirebaseVision.getInstance()
.onDeviceTextRecognizer
recognizer.processImage(visionImage)
.addOnSuccessListener { texts ->
processTextRecognitionResult(texts!!, recognizer)
if (isValidText) {
recognizer.close()
return@addOnSuccessListener
}
}
.addOnFailureListener { e -> // Task failed with an exception
e.printStackTrace()
}
}
In my project I'm using this dependencies
def firebase_version = '24.0.2'
def camerax_version = '1.0.0-beta02'
implementation "com.google.firebase:firebase-ml-vision:$firebase_version"
implementation "androidx.camera:camera-camera2:$camerax_version"
implementation "androidx.camera:camera-view:1.0.0-alpha09"
implementation "androidx.camera:camera-lifecycle:${camerax_version}"
and this is how I build CameraX
private fun bindPreview(cameraProvider: ProcessCameraProvider) {
// Get screen metrics used to setup camera for full screen resolution
val metrics = DisplayMetrics().also { viewFinder?.display?.getRealMetrics(it) }
val screenAspectRatio = aspectRatio(metrics.widthPixels, metrics.heightPixels)
val rotation = viewFinder?.display?.rotation
// Set up the preview use case to display camera preview
val preview = Preview.Builder()// Request aspect ratio but no resolution
.setTargetAspectRatio(screenAspectRatio)
// Set initial target rotation
.setTargetRotation(rotation!!)
.build()
// Choose the camera by requiring a lens facing
val cameraSelector = CameraSelector.Builder()
.requireLensFacing(CameraSelector.LENS_FACING_BACK)
.build()
val executor = Executors.newSingleThreadExecutor()
// Must unbind the use-cases before rebinding them
cameraProvider.unbindAll()
val imageAnalyzer = ImageAnalysis.Builder()
// Request aspect ratio but no resolution
.setTargetAspectRatio(screenAspectRatio)
// Set initial target rotation, have to call this again if rotation changes
// during the lifecycle of this use case
.setTargetRotation(rotation)
.setBackpressureStrategy(ImageAnalysis.STRATEGY_KEEP_ONLY_LATEST)
.build()
imageAnalyzer.setAnalyzer(executor, analyzer)
var camera = cameraProvider.bindToLifecycle(viewFinder?.context as LifecycleOwner, cameraSelector, preview, imageAnalyzer)
// Attach the viewfinder's surface provider to preview use case
preview.setSurfaceProvider(viewFinder?.createSurfaceProvider(camera.cameraInfo))
}