Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/180.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android FocusMeteringAction在最新版本的CameraX上似乎无法正常工作_Android_Android Camerax - Fatal编程技术网

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

Android FocusMeteringAction在最新版本的CameraX上似乎无法正常工作,android,android-camerax,Android,Android Camerax,为了向您提供尽可能简单的示例,我将使用Github上的存储库。我的目标是实现点击对焦功能——当用户点击预览时,相机应该在指定点对焦。我将跳过相机配置,因为所提到的存储库是一个官方示例,我们可以假设它是根据文档实现的 因此,为了拦截用户点击,我添加了这部分代码: viewFinder.setOnTouchListener { v, event -> if (event.action != MotionEvent.ACTION_UP) { return@setOnTou

为了向您提供尽可能简单的示例,我将使用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
}
值得一提的是,上述方法是基于。一切正常,除了相机聚焦错误的物体。例如,摄像机后面有两个物体:

 -------
|       |    -----
|       |   |     |
|   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该方法在最近的版本中更改为。