I'm working on an QR scanning application that is based on CameraX. The scanning works as expected on most devices except a few random devices. After debugging this issue for a long time, I found out that the cropped image is kind of shattered on the device in which scanning wasn't working.
Expected output (works on Pixel Device):
Current output (on the devices in which scanning is not working):
The analyze method that receives each frame (part of the CustomImageAnalyzer class)
override fun analyze(image: ImageProxy) {
val byteBuffer = image.planes[0].buffer
if (imageData.size != byteBuffer.capacity()) {
imageData = ByteArray(byteBuffer.capacity())
}
byteBuffer[imageData]
val iFact = if (mActivity.getOverlayView().width <= mActivity.getOverlayView().height) {
image.width / mActivity.getOverlayView().width.toDouble()
} else {
image.height / mActivity.getOverlayView().height.toDouble()
}
Log.i(TAG, "")
Log.i(TAG, "image.height" + image.height)
Log.i(TAG, "image.width" + image.width)
Log.i(TAG, "overlay.height" + mActivity.getOverlayView().height)
Log.i(TAG, "overlay.width" + mActivity.getOverlayView().width)
val size = mActivity.getOverlayView().size * iFact
Log.i(TAG, "Obtained size 1: " + mActivity.getOverlayView().size)
Log.i(TAG, "iFact: $iFact")
Log.i(TAG, "calculated size: $size")
val left = (image.width - size) / 2
val top = (image.height - size) / 2
Log.i(TAG, "left: $left")
Log.i(TAG, "top: $top")
val source = PlanarYUVLuminanceSource(
imageData,
image.width, image.height,
left.toInt(), top.toInt(),
size.toInt(), size.toInt(),
false
)
Log.i(TAG, "source.thumbnailHeight" + source.thumbnailHeight.toString())
Log.i(TAG, "source.thumbnailWidth" + source.thumbnailWidth.toString())
mActivity.runOnUiThread {
mActivity.showIntArray(source.renderThumbnail(), source.thumbnailHeight)
}
val binaryBitmap = BinaryBitmap(HybridBinarizer(source))
try {
val result = reader.decodeWithState(binaryBitmap)
listener.invoke(result.text)
} catch (e: ReaderException) {
} finally {
reader.reset()
}
// Compute the FPS of the entire pipeline
val frameCount = 10
if (++frameCounter % frameCount == 0) {
frameCounter = 0
val now = System.currentTimeMillis()
val delta = now - lastFpsTimestamp
val fps = 1000 * frameCount.toFloat() / delta
Log.d(TAG, "Analysis FPS: ${"%.02f".format(fps)}")
lastFpsTimestamp = now
}
image.close()
}
Code to start camera:
val cameraProvider: ProcessCameraProvider = cameraProviderFuture.get()
val preview = Preview.Builder()
.build()
.also {
it.setSurfaceProvider(contentFrame.surfaceProvider)
}
overlayView = findViewById(R.id.overlay)
val imageAnalysis = ImageAnalysis.Builder()
.setTargetResolution(Size(960, 960))
.build()
imageAnalysis.setAnalyzer(
executor,
QRCodeImageAnalyzer (this) { response ->
if (response != null) {
handleResult(response)
}
}
)
cameraProvider.unbindAll()
camera = cameraProvider.bindToLifecycle(this, cameraSelector, preview, imageAnalysis)
Also, I get the image from PlanarYUVLuminanceSource after the cropping is done.
Can someone please help me out with this issue?

