【问题标题】:Compile error while setting imageAnalysis.setAnalyzer()设置 imageAnalysis.setAnalyzer() 时编译错误
【发布时间】:2020-02-27 22:35:19
【问题描述】:

我正在创建一个工具来使用 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)

【问题讨论】:

    标签: android android-camerax


    【解决方案1】:

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

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

    像这样

     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 代表您要在线程池中创建的线程数。它取决于您的用例。

    告诉我它是否适合你。

    【讨论】:

    • 谢谢,但也许 AsyncTask 不是最好的解决方案?
    • 是的,它可能不是最好的解决方案@Kostya,但我不知道除了返回 Executor 实例的 AsyncTask.THREAD_POOL_EXECUTOR 之外的任何其他方式。我也在网上搜索了任何提供 Executor 实例的解决方案,但直到现在才成功找到它
    • 我已经用AsyncTask 以外的新替代方法更新了答案。如果你想要@KostyaBakay,请检查一下
    【解决方案2】:

    您还可以在官方的 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

    【讨论】:

      猜你喜欢
      • 2013-04-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-07-01
      • 1970-01-01
      • 2023-03-20
      • 2017-08-12
      相关资源
      最近更新 更多