gpt4 book ai didi

android - FocusMeteringAction 似乎无法在最新版本的 CameraX 上正常工作

转载 作者:行者123 更新时间:2023-12-04 10:28:10 30 4
gpt4 key购买 nike

为了向您提供尽可能简单的示例,我将使用 CameraXBasic Github 上的存储库。我的目标是实现点击对焦功能——当用户点击预览时,相机应该对焦在指定的点上。我将跳过相机配置,因为提到的存储库是官方示例,我们可以假设它是根据文档实现的。

所以为了拦截用户点击我添加了这部分代码:

viewFinder.setOnTouchListener { v, event ->
if (event.action != MotionEvent.ACTION_UP) {
return@setOnTouchListener true
}

val factory = SurfaceOrientedMeteringPointFactory(
v.width.toFloat(),
v.height.toFloat()
)
val focusPoint = factory.createPoint(event.x, event.y)
val focusAction = FocusMeteringAction.Builder(focusPoint).build()
camera?.cameraControl?.startFocusAndMetering(focusAction)

return@setOnTouchListener true
}

值得一提的是,上述方法是基于this blog .一切正常,除了相机聚焦在错误的物体上。例如。我们在相机后面有两个物体:

 -------
| | -----
| | | |
| A | | B |
| | | |
| | -----
-------

如您所想,对象A 比对象B 更靠近设备。当我点击 A 对象时,相机聚焦在 B 对象上。相反,当我点击 B 对象时,相机会聚焦在 A 对象上。看起来库使用的不是 event.x 值,而是 v.width - event.x 值。

要检查此行为,您可以将此问题中的代码添加到 viewFinder.post {/* */} 方法中提供的示例。

更新

this answer 中所述,问题可能与我使用的 PreviewView 有关。创建焦点时,我们必须(至少现在)将焦点转换为 PreviewView 旋转。例如。当设备处于垂直位置时,只需使用此转换:factory.createPoint(event.y, v.width - event.x)

最佳答案

上面的博文(我应该更新以明确这一点,我的错)假设取景器不使用 cameraX 的 PreviewView。使用例如 TextureView 手动设置预览并使用 Matrix 配置它可能适用于您提供的代码 fragment ,它不适用于当前 CameraXBasic 示例的原因是因为它使用 PreviewView。

PreviewView 以不同方式设置预览。首先,值得注意的是PreviewView是一个扩展FrameLayout的自定义View。它在内部添加(ViewGroup.addView())一个 TextureView(或 SurfaceView),用于处理预览 Surface。为了校正/缩放/旋转它从相机接收到的帧以适应显示器,它不使用 Matrix,而是使用实际的 View 方法(如 View.setScaleX()View.setRotation() 等)。

因此,当您调用 SurfaceOrientedMeteringPointFactory.createPoint(x, y) 时,您传入的坐标不会正确映射到预览(例如 TextureView),因为 TextureView 已被修改(旋转、放大、平移)。

要了解使用 PreviewView 实现触摸聚焦的正确方法,您可以查看 this CL最近在 AOSP 制作,特别是 this file .您可以期待触摸对焦即将推出(请密切关注 camerax-view 的下一个版本)。

编辑:

PreviewView 现在提供了一个 API 来创建计量点 ( PreviewView. createMeteringPointFactory(cameraSelector) ),它将正确处理将触摸/点击点从 PreviewView 转换为正确的坐标相机传感器。

要使用此 API 在 PreviewView 上点击聚焦,您可以编写:

final MeteringPointFactory factory = previewView.createMeteringPointFactory(cameraSelector);                
final MeteringPoint point = factory.createPoint(event.getX(), motionEvent.getY());
final FocusMeteringAction action = new FocusMeteringAction.Builder(point).build();
cameraControl.startFocusAndMetering(action)

关于android - FocusMeteringAction 似乎无法在最新版本的 CameraX 上正常工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60545408/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com