ImageAnalysis.Analyzer 只触发一次

Luk*_*uke 24 android android-camerax

在最新的 alpha ( alpha08) 中,我似乎无法弄清楚如何正确配置所有内容以便我的Analyzer正常运行。我可以看到它工作一次,然后它再也不会运行了。

由于各种原因,我需要使用 aTextureView所以我不能交换到CameraView

我几乎肯定这是由于与期货相关的事情,但我似乎无法确定。

我的想法很新鲜。任何想法/帮助表示赞赏。

我已经Application使用以下内容配置了我的课程:

override fun getCameraXConfig(): CameraXConfig {
    return Camera2Config.defaultConfig()
}
Run Code Online (Sandbox Code Playgroud)

然后以下是我的MainActivity代码(布局只是 a 中的TextureView一个ConstraintLayout):

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import android.util.Size
import android.view.Surface
import android.view.TextureView
import androidx.camera.core.*
import androidx.camera.lifecycle.ProcessCameraProvider
import androidx.concurrent.futures.CallbackToFutureAdapter
import androidx.core.content.ContextCompat
import androidx.lifecycle.LifecycleOwner
import com.google.common.util.concurrent.ListenableFuture
import java.util.concurrent.Executors

class MainActivity : AppCompatActivity() {

    private lateinit var viewFinder: TextureView
    private lateinit var cameraProviderFuture : ListenableFuture<ProcessCameraProvider>
    private val executor = Executors.newSingleThreadExecutor()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        cameraProviderFuture = ProcessCameraProvider.getInstance(this)
        viewFinder = findViewById(R.id.view_finder)     // TextureView
        startCamera()
    }

    private fun startCamera() {
        val preview = Preview.Builder().apply {
            setTargetResolution(Size(640, 480))
        }.build()
        preview.setPreviewSurfaceProvider { resolution, surfaceReleaseFuture ->
            viewFinder.surfaceTexture.setDefaultBufferSize(resolution.width, resolution.height)
            val surface = Surface(viewFinder.surfaceTexture)
            surfaceReleaseFuture.addListener(
                Runnable {
                    surface.release()
                    viewFinder.surfaceTexture.release()
                },
                ContextCompat.getMainExecutor(this)
            )
            CallbackToFutureAdapter.getFuture<Surface> { completer -> completer.set(surface) }
        }

        val analyzer = ImageAnalysis.Builder().build()
        val analyzerUseCase = analyzer.apply {
            setAnalyzer(executor, MyTestAnalyzer())
        }

        val cameraSelector = CameraSelector.Builder().requireLensFacing(CameraSelector.LENS_FACING_BACK).build()
        cameraProviderFuture.addListener(Runnable {
            val cameraProvider = cameraProviderFuture.get()
            cameraProvider.bindToLifecycle(this as LifecycleOwner, cameraSelector, analyzerUseCase, preview)
        }, ContextCompat.getMainExecutor(this))
    }
}

private class MyTestAnalyzer : ImageAnalysis.Analyzer {
    override fun analyze(image: ImageProxy) {
        Log.d("Sandbox", "### Would analyze the image here ...")
    }
}
Run Code Online (Sandbox Code Playgroud)

Luk*_*uke 76

我决定在这里为后代回答我自己的问题,因为我从另一个渠道得到了答案。

API 最近发生了变化,这意味着您需要ImageProxy#close手动调用。CameraX 过去会自动调用它。从文档:

应用程序有责任在完成后关闭图像。如果图像没有关闭,那么它可能会阻止生成更多图像(导致预览停止)或丢弃由配置的背压策略确定的图像。确切的行为可通过 ImageAnalysis.Builder.setBackpressureStrategy(int) 进行配置。

此更改允许在如何进行帧分析(例如:多帧分析)方面具有更大的灵活性,因为您现在可以完全控制何时清除帧。

所以你的分析器代码应该是:

override fun analyze(image: ImageProxy) {
    Log.d("Sandbox", "### Would analyze the image here ...")
    image.close()
}
Run Code Online (Sandbox Code Playgroud)

此处的完整详细信息:https : //developer.android.com/training/camerax/analyze