【问题标题】:Implement Tap to Focus in Camera2 API在 Camera2 API 中实现 Tap to Focus
【发布时间】:2015-10-15 14:30:00
【问题描述】:

我想在我的自定义相机中实现点按对焦功能。 这是谷歌提供的基本代码https://github.com/googlesamples/android-Camera2Basic

这是我认为应该添加我的功能的代码 sn-p 如果有人实现了 Camera2 API,请帮忙!

  private void lockFocus() {
    try {
        // This is how to tell the camera to lock focus.
        mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER,
                CameraMetadata.CONTROL_AF_TRIGGER_START);
        // Tell #mCaptureCallback to wait for the lock.
        mState = STATE_WAITING_LOCK;
        mCaptureSession.capture(mPreviewRequestBuilder.build(), mCaptureCallback,
                mBackgroundHandler);
    } catch (CameraAccessException e) {
        e.printStackTrace();
    }
}

【问题讨论】:

    标签: android


    【解决方案1】:

    您需要将自动对焦和自动曝光区域设置为用户点击的区域。

    密钥是CONTROL_AF_REGIONSCONTROL_AE_REGIONS

    它们的单位在传感器 active array coordinate system 中,因此您必须将 UI 触摸坐标转换为相对于预览视图的坐标,然后再转换为活动数组坐标。

    如果预览的纵横比与传感器的纵横比相匹配,那就很简单了;如果没有,您将不得不调整为创建预览输出而完成的裁剪。目前关于裁剪工作原理的最佳图表是here。请注意,如果您还应用了缩放,则需要在计算中也包含缩放因子。

    计算完区域后,您可能希望将 AF 模式设置为 AUTO(而不是通常用于正常预览的 CONTINUOUS_PICTURE),然后触发 AF。一旦收敛 AF(查看捕捉结果中的 AF 状态,等待 AF_STATE_FOCUSED_LOCKED),您就可以拍出清晰对焦的照片了。如果您想在一段时间后恢复正常操作或用户取消触摸对焦,请将 AF 模式切换回 CONTINUOUS_PICTURE。

    【讨论】:

      【解决方案2】:
      1. 使用 onTouch 侦听器获取用户触摸屏幕的点。
      2. 根据该位置计算一个/一些MeteringRectangle(s)
      3. 使用此计量矩形设置CaptureRequest.CONTROL_AF_REGION & CaptureRequest.CONTROL_AE_REGION

      4. CaptureRequest.CONTROL_AF_MODE 设置为 CaptureRequest.CONTROL_AF_MODE_AUTO

      5. CaptureRequest.CONTROL_AF_TRIGGER 至 CameraMetadata.CONTROL_AF_TRIGGER_START
      6. CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER 到 CameraMetadata.CONTROL_AE_TRIGGER_START

      7. 然后构建捕获请求


      Here你可以找到一个完整的例子。


      【讨论】:

        【解决方案3】:
         public void handleFocus(MotionEvent event) {
            int pointerId = event.getPointerId(0);
            int pointerIndex = event.findPointerIndex(pointerId);
            // Get the pointer's current position
            float x = event.getX(pointerIndex);
            float y = event.getY(pointerIndex);
        
            Rect touchRect = new Rect(
                    (int) (x - 100),
                    (int) (y - 100),
                    (int) (x + 100),
                    (int) (y + 100) );
        
        
            if (mCameraId == null) return;
            CameraManager cm = (CameraManager)this.getSystemService(Context.CAMERA_SERVICE);
            CameraCharacteristics cc = null;
            try {
                cc = cm.getCameraCharacteristics(mCameraId);
            } catch (CameraAccessException e) {
                e.printStackTrace();
            }
        
        
            MeteringRectangle focusArea = new MeteringRectangle(touchRect,MeteringRectangle.METERING_WEIGHT_DONT_CARE);
            mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER, CameraMetadata.CONTROL_AF_TRIGGER_CANCEL);
            try {
                mCaptureSession.capture(mPreviewRequestBuilder.build(), mCaptureCallback,
                        mBackgroundHandler);
                // After this, the camera will go back to the normal state of preview.
                mState = STATE_PREVIEW;
            } catch (CameraAccessException e){
                // log
            }
        
            /* if (isMeteringAreaAESupported(cc)) {
             *//*mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AE_REGIONS,
                        new MeteringRectangle[]{focusArea});*//*
            }
            if (isMeteringAreaAFSupported(cc)) {
                *//*mPreviewRequestBuilder
                        .set(CaptureRequest.CONTROL_AF_REGIONS, new MeteringRectangle[]{focusArea});
                mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_MODE,
                        CaptureRequest.CONTROL_AF_MODE_AUTO);*//*
            }*/
            mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AE_REGIONS,
                    new MeteringRectangle[]{focusArea});
            mPreviewRequestBuilder
                    .set(CaptureRequest.CONTROL_AF_REGIONS, new MeteringRectangle[]{focusArea});
            mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_MODE,
                    CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);
            mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER,
                    CameraMetadata.CONTROL_AF_TRIGGER_START);
            mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER,
                    CameraMetadata.CONTROL_AE_PRECAPTURE_TRIGGER_START);
            try {
                mCaptureSession.setRepeatingRequest(mPreviewRequestBuilder.build(), mCaptureCallback,
                        mBackgroundHandler);
                /* mManualFocusEngaged = true;*/
            } catch (CameraAccessException e) {
                // error handling
            }
        }
        

        在 averide on touch 中调用触摸事件方法

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2013-03-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-07-23
          • 2010-10-18
          • 2020-09-20
          • 1970-01-01
          相关资源
          最近更新 更多