如何在CameraX中镜像PreviewView?

rdx*_*dkr 5 android android-view android-camerax

免责声明:我知道这个问题的存在,但它目前尚未解决,我试图提供额外的信息,而不用无用的答案污染该问题,无论如何都无法解决问题。

我有一个带有默认镜像的前置摄像头的自定义设备,因此我想正常显示预览,并且需要水平翻转PreviewView的内容,但我被卡住了。过去其他人建议使用,PreviewView#setScaleX(-1)但它要么根本不起作用,要么需要在代码中的一个非常特定的点调用它,而我还没有找到。

下面的代码是CameraFragment.kt官方CameraXBasic示例中的简化版本;我已经添加了评论,我已经厌倦了打电话viewFinder.scaleX = -1f但没有成功。老实说,我真的不认为这个地方有什么区别,因为如果我用 1 以外的任何值调用它,它与 和 都可以正常工作scaleXscaleY它总是忽略负号,所以它永远不会翻转。

private lateinit var viewFinder: PreviewView

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    ...
    viewFinder = view.findViewById(R.id.view_finder)
    // HERE
    viewFinder.post {
        // HERE
        setupCamera()
    }
}

private fun setupCamera() {
    val cameraProviderFuture = ProcessCameraProvider.getInstance(requireContext())
    cameraProviderFuture.addListener(Runnable {
        val cameraProvider = cameraProviderFuture.get()

        val cameraSelector = CameraSelector.Builder()
            .requireLensFacing(CameraSelector.LENS_FACING_FRONT)
            .build()

       val preview = Preview.Builder()
            .build()
            .also {
                // HERE
                it.setSurfaceProvider(viewFinder.surfaceProvider)
            }

       cameraProvider.unbindAll()

        try {
            cameraProvider.bindToLifecycle(this, cameraSelector, preview)
            // HERE
        } catch (exc: Exception) {
            Log.e(TAG, "Use case binding failed", exc)
        }
        // HERE
    }, ContextCompat.getMainExecutor(requireContext()))
    // HERE
}
Run Code Online (Sandbox Code Playgroud)

Hus*_*eem 8

根据实现类型 ( COMPATIBLEvs PERFORMANCE) 和设备,PreviewView可以使用 aTextureView或 a SurfaceView,在您的情况下,我假设PreviewView使用 a SurfaceView,您可以通过访问PreviewView第一个子视图 ( View.getChildAt(0)) 来确认这一点。

TextureView就像任何其他一样View,这就是为什么在PreviewView使用它时,将其scaleX设置为-1应该镜像显示的预览。PreviewView.setScaleX(-1F)您可以在创建布局后调用(例如 In onViewCreated())。

对于SurfaceView,这有点棘手,因为Surface和在某些方面View独立的Surface:放置在保存 的窗口后面View,并且视图层次结构通过在窗口中打孔以显示 来正确处理整个布局SurfaceViewSurfaceSurfaceView这可能解释了为什么无法镜像内容显示,尽管我不确定为什么放大(scaleX 设置为值 > 1)和缩小(scaleX 设置为 0 到 1 之间的值)仍然有效。

  • 我问了一个[新问题](/sf/ask/4591686781/),其中包含有关我的更多详细信息试图实现。我开始使用 CameraX,因为它在一般使用相机和调用 MLKit API 方面都需要最少的工作量,但由于这些怪癖,我不再 100% 确定。 (2认同)