简体   繁体   English

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

[英]Tap to adjust focus / exposure in CameraX

I would like to implement the standard UX of tapping a point on the preview to adjust the auto-focus and auto-exposure points to the place where they tapped. 我想实现标准的UX,即在预览中点击一个点,以将自动聚焦和自动曝光点调整到它们所点击的位置。 I found the Preview.focus() function, however it says that it needs dimensions in the "sensor coordinate frame", which I'm assuming is not the same as the TextureView's TouchEvent pixel coordinates. 我找到了Preview.focus()函数,但是它说它需要“传感器坐标系”中的尺寸,我认为这与TextureView的TouchEvent像素坐标不同。

How do I convert from the TextureView preview's touch coordinates to the "sensor coordinate frame" expected by Preview.focus()? 如何从TextureView预览的触摸坐标转换为Preview.focus()期望的“传感器坐标框架”?

It would be great if this example was part of the sample code, as it seems like a pretty common use case that nearly everyone will expect. 如果此示例是示例代码的一部分,那就太好了,因为这似乎是几乎每个人都会期望的非常普遍的用例。

TextureView's coordinates are not the same as sensor coordinates. TextureView的坐标与传感器坐标不同。 Please refer to the sample codes here (Please note that the "CameraView" is not public in maven repository yet. So we do not encourage you use it now). 在此处参考示例代码(请注意,“ CameraView”尚未在maven存储库中公开。因此,我们不建议您现在使用它)。 We understand these are a lot of work so CameraX team is also developing a more developer-friendly version of focus/metering API. 我们知道这些工作量很大,因此CameraX团队还在开发对开发人员更友好的焦点/测光API版本。

The basic flow is as below: (1) get x, y from a view touch event. 基本流程如下:(1)从视图触摸事件获取x,y。 (2) Calculate the relative camera orientation using device orientation and camera2 CameraCharacteristics.SENSOR_ORIENTATION. (2)使用设备方向和camera2 CameraCharacteristics.SENSOR_ORIENTATION计算相对摄像机方向。 The value represents the clockwise angle through which the sensor image needs to be rotated to be upright in current device orientation. 该值表示顺时针旋转的角度,传感器图像需要旋转该角度才能在当前设备方向上直立。
(3) swap x, y for 90 / 270 degree , and reverse the x, y properly by the orientation. (3)将x,y换成90/270度,并按方向正确反转x,y。 reverse the x for mirroring (front camera) (4) transform to the sensor coordinates using CameraCharacteristics.SENSOR_INFO_ACTIVE_ARRAY_SIZE), view width/height . 反转x以进行镜像(前置摄像头)(4),使用CameraCharacteristics.SENSOR_INFO_ACTIVE_ARRAY_SIZE转换为传感器坐标,并查看宽度/高度。

note: for the camera id, for now you can get find first camera_id in mCameraManager.getCameraIdList() with correct lens facing. 注意:对于相机ID,现在您可以在mCameraManager.getCameraIdList()中以正确的镜头朝向找到第一个camera_id。 however the algorithm could be changed. 但是可以更改算法。

This blog post written by a Google engineer explains exactly how to do it (in Kotlin). 由Google工程师撰写的这篇博客文章准确地解释了如何做到这一点(在Kotlin中)。

This is how to achieve the same in Java: 这是在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;
        }
    });
}

The cameraControl object can be instantiated like this: cameraControl对象可以像这样实例化:

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

but make sure you have 但请确保您有

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

within your build.gradle dependencies. build.gradle依赖项中。


For reference, here's the original Kotlin code from Husayn Hakeem blog post : 作为参考,这是来自Husayn Hakeem博客文章的原始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
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM