设置 imageAnalysis.setAnalyzer() 时编译错误

Compile error while setting imageAnalysis.setAnalyzer()

我正在创建一个工具来使用 cameraX 捕获预览中的每一帧(用于人脸识别)

我发现使用 ImageAnalysis 是正确的选择。

直到我尝试使用推荐的代码:

val imageAnalysisConfig = ImageAnalysisConfig.Builder()
            .setTargetResolution(Size(1280, 720))
            .setImageReaderMode(ImageAnalysis.ImageReaderMode.ACQUIRE_LATEST_IMAGE)
            .build()
        val imageAnalysis = ImageAnalysis(imageAnalysisConfig)

        imageAnalysis.setAnalyzer({ image: ImageProxy, rotationDegrees: Int ->
            viewModel.onAnalyzeImage(image)
        })

我在 setAnalyser 方法上得到以下编译错误:

None of the following function can be called with the arguments supplied
setAnalyser((command : Runnable!) -> Unit,  (image: ImageProxy!, rotationDegrees: Int) -> Unit)

我今天也遇到了同样的问题,所以,发现少了一个参数Executor,我们需要传递这个参数,否则会出现同样的编译错误。

在我过去使用 AsyncTasks 时,我认识到要在 AsyncTasks 中的多线程中执行任务,我们需要使用它的静态方法 executeOnExecutor() Executor 作为它的参数,所以我使用了相同的参数,即我在 setAnalyser() 方法中使用 AsyncTask.THREAD_POOL_EXECUTOR 作为第一个参数。它就像一个魅力!将其作为第一个参数后,您需要对之前的代码进行一些小改动。

像这样

 imageAnalysis.setAnalyzer(AsyncTask.THREAD_POOL_EXECUTOR,
 object : ImageAnalysis.Analyzer {    // changes to be done in this line
                    override fun analyze(imageProxy: ImageProxy, rotationDegrees: Int) {
                        val image = FirebaseVisionImage.fromMediaImage(
                                imageProxy.image!!, getFirebaseRotation(rotationDegrees)
                        )
        
                        if (processingBarcode.get() ||
                                !lifecycle.currentState.isAtLeast(Lifecycle.State.RESUMED)) {
                            return
                        }
    ..................
    .............
    .......BLA BLA BLA
    }

尝试一下并告诉我这种方法是否适用于您的用例。

编辑

如果您不喜欢 AsyncTask,那么我找到了一种替代方法,可以在不使用 AsyncTask.THREAD_POOL_EXECUTOR.

的情况下获取 Executor 实例

您可以使用 Executors.newFixedThreadPool(n) 来获取 Executor 实例。 此处,n 代表您要在线程中创建的线程数 pool.It 因您的用例而异。

告诉我它是否适合你。

您还可以在官方 CameraX 示例应用中找到实现: CameraFragment.kt.

您需要的部分是:

// Executor field
private lateinit var analysisExecutor: Executor

// in onCreate()
analysisExecutor = Executors.newSingleThreadExecutor()

// after initializing imageAnalysis
imageAnalysis.setAnalyzer(analysisExecutor, ImageAnalysis.Analyzer {
    // TODO analyze
})

如果您想知道是使用 Executors.newSingleThreadExecutor()Executors.newFixedThreadPool(n) 还是其他,请查看 Executors documentation.