【问题标题】:CameraX | Enable/Disable image analysis相机X |启用/禁用图像分析
【发布时间】:2020-02-20 14:47:40
【问题描述】:

我正在尝试使用 CameraX 和 ZXing 条码扫描库来实现条码扫描器。

我编写了一个自定义分析器来解码条形码并且应该处理这些条形码(处理逻辑显然需要一些时间)。

所以我想要的是动态禁用图像分析,如果处理操作的结果不成功,则再次启用它。

我的基本设置逻辑:

    private fun setupCamera() {
        processCameraProvider.unbindAll()
        val camera = processCameraProvider.bindToLifecycle(
            this,
            CameraSelector.DEFAULT_BACK_CAMERA,
            buildPreviewUseCase(),
            buildImageAnalysisUseCase())
    }

    private fun buildPreviewUseCase(): Preview {
        return Preview.Builder()
            .setTargetRotation(cameraPreview.display.rotation)
            .build()
            .apply {
                previewSurfaceProvider = cameraPreview.previewSurfaceProvider
            }
    }

    private fun buildImageAnalysisUseCase(): ImageAnalysis {
        return ImageAnalysis.Builder()
            .setTargetRotation(cameraPreview.display.rotation)
            .setBackpressureStrategy(ImageAnalysis.STRATEGY_KEEP_ONLY_LATEST)
            .build()
            .apply {
                setAnalyzer(Executors.newSingleThreadExecutor(),
                    ZxingBarcodeAnalyzer { qrResult ->
                        Handler(Looper.getMainLooper()).post {
                            viewModel.handleBarcode(qrResult.text)
                        }
                    })
            }
    }

在挖掘了库资源之后,我仍然不明白如何实现所需的行为?

如果我在processCameraProvider 上调用unbind(imageAnalysisUseCase object),我将无法再次绑定该对象(processCameraProvider 只有bindToLifecycle() 方法,而不是bind(imageAnalysisUseCase object))。

ImageAnalysis 上调用clearAnalyzer() 会完全重置图像分析,尽管再次调用setAnalyzer()

【问题讨论】:

  • 你设法让它工作了吗?

标签: android android-camerax


【解决方案1】:

clearAnalyzer() 存在问题

我一直这样使用,直到修复:

  fun enableAnalysis(enable: Boolean) {
    if (!enable) {
        isAnalyzerSet = false
        imageAnalysisUseCase?.clearAnalyzer()
        imageAnalysisUseCase.setAnalyzer(analysisExecutor, ImageAnalysis.Analyzer { })

    } else {
        if (isAnalyzerSet) return
        isAnalyzerSet = true
        imageAnalysisUseCase?.setAnalyzer(analysisExecutor, analyzer)
    }
}

【讨论】:

  • 是哪个版本的问题?
  • 我在重新启动分析器时遇到了同样的问题,但它不起作用。我的问题是,我没有做 imageProxy.close()
【解决方案2】:

如果您只想在处理图像时不处理任何图像,您可以在分析方法中设置一个标签,如果正在处理图像,该标签会立即返回。像这样的:

class MyViewModel: ViewModel() {

    private var isProcessing = false

    fun handleBarcode(text: String) {
        if (isProcessing) {
            return
        }
        // Do your processing here.
    }
}

如果您调用processCameraProvider.unbind(imageAnalysis),您可以通过使用同一实例调用processCameraProvider.bindToLifecycle(, , imageAnalysis) 再次绑定用例,但我不确定这是否可行。重新绑定相同的预览用例实例不起作用,我不确定该规则是否适用于 ImageAnalysis。

【讨论】:

    【解决方案3】:

    您可以要求制作者一次生成一张图像,直到您关闭代理。

    ImageAnalysis imageAnalysis = imageAnalysisBuilder.setBackpressureStrategy(ImageAnalysis.STRATEGY_BLOCK_PRODUCER).setImageQueueDepth(1).build();
    

    从文档中, https://developer.android.com/reference/androidx/camera/core/ImageAnalysis#STRATEGY_BLOCK_PRODUCER

    阻止生产者生成新图像。

    一旦生产者产生的图像数量等于图像 队列深度,并且没有关闭,生产者将停止 产生图像。请注意,图像可能会在内部排队,而不是 传送到分析仪,直到最后传送的图像已经 用 ImageProxy.close() 关闭

    【讨论】:

      猜你喜欢
      • 2022-07-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-11-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多