Android FocusMeteringAction在最新版本的CameraX上似乎无法正常工作
为了向您提供尽可能简单的示例,我将使用Github上的存储库。我的目标是实现点击对焦功能——当用户点击预览时,相机应该在指定点对焦。我将跳过相机配置,因为所提到的存储库是一个官方示例,我们可以假设它是根据文档实现的 因此,为了拦截用户点击,我添加了这部分代码:Android FocusMeteringAction在最新版本的CameraX上似乎无法正常工作,android,android-camerax,Android,Android Camerax,为了向您提供尽可能简单的示例,我将使用Github上的存储库。我的目标是实现点击对焦功能——当用户点击预览时,相机应该在指定点对焦。我将跳过相机配置,因为所提到的存储库是一个官方示例,我们可以假设它是根据文档实现的 因此,为了拦截用户点击,我添加了这部分代码: viewFinder.setOnTouchListener { v, event -> if (event.action != MotionEvent.ACTION_UP) { return@setOnTou
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
}
值得一提的是,上述方法是基于。一切正常,除了相机聚焦错误的物体。例如,摄像机后面有两个物体:
-------
| | -----
| | | |
| A | | B |
| | | |
| | -----
-------
可以想象,对象A比对象B更接近设备。当我点击A对象时,相机聚焦在B对象上。相反,当我点击B对象时,相机聚焦在A对象上。看起来库使用的不是event.x
值,而是v.width-event.x
值
要检查此行为,可以在viewFinder.post{/**/}
方法中将此问题中的代码添加到提供的示例中
更新
如中所述,该问题可能与我正在使用的PreviewView
有关。创建焦点时,我们必须(至少现在)将该点平移到PreviewView
旋转。例如,当设备处于垂直位置时,只需使用以下转换:factory.createPoint(event.y,v.width-event.x)
上面的博客文章(我应该更新以明确这一点,我的错)假设取景器不使用cameraX的PreviewView。例如,通过使用TextureView手动设置预览,并使用矩阵对其进行配置,这可能适用于您提供的代码段,它不适用于当前CameraXBasic示例的原因是它使用PreviewView
PreviewView以不同的方式设置预览。首先,值得注意的是PreviewView是一个扩展FrameLayout的自定义视图。它在内部添加()一个TextureView(或SurfaceView),用于处理预览曲面。为了校正/缩放/旋转从相机接收到的帧以使其适应显示,它不使用矩阵,而是使用实际的视图方法(如等)
因此,当您调用SurfaceOrientedMeteringPointFactory.createPoint(x,y)
时,您传递的坐标无法正确映射到预览(例如TextureView),因为TextureView已被修改(旋转、放大、平移)
为了了解使用PreviewView实现触摸对焦的正确方法,您可以看看最近在AOSP中制作的,尤其是。您可以期待touch-to-focus即将面世(密切关注camerax view的下一版本)
编辑:
PreviewView
现在提供了一个创建测光点的API(),它将正确处理从PreviewView
到相机传感器上正确坐标的触摸/点击点转换
要将此API用于tap以关注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)
谢谢,正如您提到的,我必须将点从事件转换为
PreviewView
rotation。您好,请问哪个版本的库包含createMeteringPointFactory for PreviewView?我有上一个androidx。camera:camera view:1.0.0-alpha17,但这个方法不在类中。@PetrDaňa该方法在最近的版本中更改为。