CameraX:ImageAnalysis 的输出看起来 corrupted/scattered

CameraX: Output of ImageAnalysis looks corrupted/scattered

我正在开发基于 CameraX 的 QR 扫描应用程序。除少数随机设备外,扫描在大多数设备上都按预期工作。这个问题调试了半天,发现裁剪后的图片在无法扫描的设备上有点碎裂。

预期输出(适用于 Pixel 设备):

当前输出(在扫描不工作的设备上):

接收每一帧的analyze方法(CustomImageAnalyzerclass的一部分)

    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()
    }

启动相机的代码:

                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)

此外,我在裁剪完成后从 PlanarYUVLuminanceSource 获取图像。

有人可以帮我解决这个问题吗?

有些设备有旋转功能。您可以使用 imageProxy.getImageInfo().getRotationDegrees() 来获得正确的图像旋转。引用 (ImageInfo) https://developer.android.com/reference/androidx/camera/core/ImageInfo#getRotationDegrees()