点按以在CameraX中调整焦点/曝光

时间:2019-05-30 18:45:24

标签: android android-camerax

我想实现标准的UX:在预览上点击一个点,以将自动聚焦和自动曝光点调整到它们所点击的位置。我找到了Preview.focus()函数,但是它说它需要“传感器坐标系”中的尺寸,我认为这与TextureView的TouchEvent像素坐标不同。

如何将TextureView预览的触摸坐标转换为Preview.focus()所需的“传感器坐标框架”?

如果此示例是示例代码的一部分,那就太好了,因为这似乎是几乎每个人都会期望的非常常见的用例。

2 个答案:

答案 0 :(得分:0)

TextureView的坐标与传感器坐标不同。请参考示例代码https://vaex.readthedocs.io/en/latest/(请注意,“ CameraView”尚未在maven存储库中公开。因此,我们不建议您现在使用它)。我们知道这些工作量很大,因此CameraX团队还在开发对开发人员更友好的焦点/测光API版本。

基本流程如下: (1)从视图触摸事件获取x,y。 (2)使用设备方向和camera2 CameraCharacteristics.SENSOR_ORIENTATION计算相对摄像机方向。该值表示顺时针旋转的角度,传感器图像需要旋转该角度才能在当前设备方向上直立。
(3)将x,y换成90/270度,并按方向正确反转x,y。反转x进行镜像(前置摄像头) (4)使用CameraCharacteristics.SENSOR_INFO_ACTIVE_ARRAY_SIZE)转换为传感器坐标,查看宽度/高度。

注意:对于相机ID,现在您可以在mCameraManager.getCameraIdList()中找到第一个带有正确镜头朝向的camera_id。但是可以更改算法。

答案 1 :(得分:0)

由Google工程师撰写的

This blog post(在Kotlin中)确切地解释了如何做到这一点。

这是在Java中实现相同效果的方法:

private void setUpTapToFocus() {
    textureView.setOnTouchListener(new OnTouchListener() {
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            if (event.getAction() != MotionEvent.ACTION_UP) {
                /* Original post returns false here, but in my experience this makes
                onTouch not being triggered for ACTION_UP event */
                return true;
            }
            TextureViewMeteringPointFactory factory = new TextureViewMeteringPointFactory(textureView);
            MeteringPoint point = factory.createPoint(event.getX(), event.getY());
            FocusMeteringAction action = FocusMeteringAction.Builder.from(point).build();    
            cameraControl.startFocusAndMetering(action);
            return true;
        }
    });
}

cameraControl对象可以这样实例化:

CameraControl cameraControl = CameraX.getCameraControl(CameraX.LensFacing.BACK);

但请确保您拥有

implementation "androidx.camera:camera-view:1.0.0-alpha03"

在您的build.gradle依赖项之内。


作为参考,这是来自Husayn Hakeem blog post的原始Kotlin代码:

private fun setUpTapToFocus() {
    textureView.setOnTouchListener { _, event ->
        if (event.action != MotionEvent.ACTION_UP) {
            return@setOnTouchListener false
        }

        val factory = TextureViewMeteringPointFactory(textureView)
        val point = factory.createPoint(event.x, event.y)
        val action = FocusMeteringAction.Builder.from(point).build()
        cameraControl.startFocusAndMetering(action)
        return@setOnTouchListener true
    }
}