Android camera2 api touch聚焦示例? [英] Android camera2 api touch to focus example?

查看:279
本文介绍了Android camera2 api touch聚焦示例?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用camera2basic示例来实现我的camera2应用程序.我找不到任何很好的示例来实现使用camera2 API进行触摸对焦.目前,我用于触摸焦点的代码是:

Hi I'm using camera2basic example to implement my camera2 application. I can't find any good example to implement touch to focus with camera2 api. Currently the code i'm using for touch to focus is this:

    private void setFocusArea(MotionEvent event) {
    if (mCameraId == null) return;
    CameraManager cm = (CameraManager)getActivity().getSystemService(Context.CAMERA_SERVICE);
    CameraCharacteristics cc = null;
    try {
        cc = cm.getCameraCharacteristics(mCameraId);
    } catch (CameraAccessException e) {
        e.printStackTrace();
    }

    int myX = (int)event.getX();
    int myY = (int)event.getY();
    MeteringRectangle focusArea = new MeteringRectangle(myX-100,myY-100,200,200,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_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
    }
}

但是问题在于它表现出奇怪的行为,自动闪光功能会不断重复自动对焦序列无限次,而且似乎也不会专注于触摸的区域.我尝试改变

But the problem is that it shows strange behavior, with auto-flash on it keeps repeating the auto-focus sequence for unlimited times also it doesnot seem to focus on the touched area. I tried changing

mCaptureSession.setRepeatingRequest(mPreviewRequestBuilder.build(), mCaptureCallback, mBackgroundHandler);

收件人:

mCaptureSession.capture(mPreviewRequestBuilder.build(), mCaptureCallback, mBackgroundHandler);

这停止了重复的自动对焦序列,但仍不对焦于触摸的区域,闪光灯仅闪烁了不到一秒钟,而不是正常的对焦序列.请对此提供帮助或引导我进行工作,以使示例更突出.谢谢

this stopped the repeating auto-focus sequence but it still doesn't focus on the touched area and the flash just blinks for less than a second instead of a normal focus sequence. Please help me with this or guide me to a working touch to focus example. Thanks

推荐答案

您的问题是设置AF区域的控件.

Your problem is setting the AF region's control.

  1. 计算要设置焦点的区域
  2. 停止当前会话 mPreviewSession.stopRepeating()
  3. 启动自动对焦触发!

3.1.安全地开始使AF区域变为空闲状态

3.1. Safely start to make the AF region IDLE

3.2.然后启动自动对焦触发

3.2. then start AF trigger

        mCaptureRequestBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER, CameraMetadata.CONTROL_AF_TRIGGER_IDLE);
        mCaptureRequestBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER, CameraMetadata.CONTROL_AF_TRIGGER_START);

  1. 捕获一次即可应用您的设置

  1. Capture once to apply your settings

检查是否支持AF和AE区域(如果支持),请应用该区域

Check if AF and AE regions are supported or not is supported If supported then apply this region

if ( isMeteringAreaAESupported()) {
    //System.out.println("AE regions are supported");
    mCaptureRequestBuilder.set(CaptureRequest.CONTROL_AE_REGIONS, new MeteringRectangle[]{focusArea});
}
if (  isMeteringAreaAFSupported()) {
    //System.out.println("AF regions are supported");

    mCaptureRequestBuilder.set(CaptureRequest.CONTROL_AF_REGIONS, new MeteringRectangle[]{focusArea});
    mCaptureRequestBuilder.set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_AUTO);
}

  • 再次捕捉一次即可设置焦点

  • Again capture once to set the focus

     mPreviewCaptureSession.capture(mCaptureRequestBuilder.build(), mCaptureCallback, mBackgroundHandler);
    

  • mCaptureCallback 内,您应该取消AF触发,但是文档说AF触发在某些设备中可以为空,所以我很喜欢

  • inside mCaptureCallback you should cancel AF trigger, but the documentation says AF trigger can be null in some device so I did like

    mCaptureRequestBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER, CameraMetadata.CONTROL_AF_TRIGGER_IDLE);
    mCaptureRequestBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER, CameraMetadata.CONTROL_AF_TRIGGER_CANCEL);
    mCaptureRequestBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER, null);
    

  • 最后一件事是 mPreviewCaptureSession.setRepeatingRequest(mCaptureRequestBuilder.build(),null,mBackgroundHandler);

    编辑

    这是工作示例

    private void setFocusArea(int focus_point_x, int focus_point_y) throws CameraAccessException {
    
    if (cameraId == null || mManualFocusEngaged) return;
    
    if (mCameraManager == null){
        mCameraManager = (CameraManager) mContext.getSystemService(Context.CAMERA_SERVICE);
    }
    
    MeteringRectangle focusArea = null;
    
    if (mCameraManager != null) {
        if (mCameraCharacteristics == null) {
            mCameraCharacteristics = mCameraManager.getCameraCharacteristics(cameraId);
        }
    
        final Rect sensorArraySize = mCameraCharacteristics.get(CameraCharacteristics.SENSOR_INFO_ACTIVE_ARRAY_SIZE);
    
        int y = focus_point_x;
        int x = focus_point_y;
    
        if (sensorArraySize != null) {
            y = (int)(((float)focus_point_x / currentWidth)  * (float)sensorArraySize.height());
            x = (int)(((float)focus_point_y / currentHeight) * (float)sensorArraySize.width());
        }
    
        final int halfTouchLength  = 150;
        focusArea = new MeteringRectangle(Math.max(x - halfTouchLength,  0),
                Math.max(y - halfTouchLength, 0),
                halfTouchLength  * 2,
                halfTouchLength * 2,
                MeteringRectangle.METERING_WEIGHT_MAX - 1);
    }
    
    CameraCaptureSession.CaptureCallback mCaptureCallback = new CameraCaptureSession.CaptureCallback() {
    
        @Override
        public void onCaptureCompleted(@NonNull CameraCaptureSession session, @NonNull CaptureRequest request, @NonNull TotalCaptureResult result) {
            super.onCaptureCompleted(session, request, result);
    
            mManualFocusEngaged = false;
    
            if (request.getTag().equals(FOCUS_TAG)) { // previously getTag == "Focus_tag"
                //the focus trigger is complete -
                //resume repeating (preview surface will get frames), clear AF trigger
                mCaptureRequestBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER, CameraMetadata.CONTROL_AF_TRIGGER_IDLE);
                mCaptureRequestBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER, CameraMetadata.CONTROL_AF_TRIGGER_CANCEL);
                mCaptureRequestBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER, null);// As documentation says AF_trigger can be null in some device
                try {
                    mCurrentCameraCaptureSession.setRepeatingRequest(mCaptureRequestBuilder.build(), null, mBackgroundHandler);
                } catch (CameraAccessException e) {
                    // error handling
                }
            }
        }
    
        @Override
        public void onCaptureFailed(@NonNull CameraCaptureSession session, @NonNull CaptureRequest request, @NonNull CaptureFailure failure) {
            super.onCaptureFailed(session, request, failure);
            mManualFocusEngaged = false;
        }
    
    };
    
    mCurrentCameraCaptureSession.stopRepeating(); // Destroy current session
    mCaptureRequestBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER, CameraMetadata.CONTROL_AF_TRIGGER_IDLE);
    mCaptureRequestBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER, CameraMetadata.CONTROL_AF_TRIGGER_START);
    mCurrentCameraCaptureSession.capture(mCaptureRequestBuilder.build(), mCaptureCallback, mBackgroundHandler); //Set all settings for once
    
    if ( isMeteringAreaAESupported()) {
        mCaptureRequestBuilder.set(CaptureRequest.CONTROL_AE_REGIONS, new MeteringRectangle[]{focusArea});
    }
    if ( isMeteringAreaAFSupported()) {
        mCaptureRequestBuilder.set(CaptureRequest.CONTROL_AF_REGIONS, new MeteringRectangle[]{focusArea});
        mCaptureRequestBuilder.set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_AUTO);
    }
    
    mCaptureRequestBuilder.setTag(FOCUS_TAG); //it will be checked inside mCaptureCallback
    mCurrentCameraCaptureSession.capture(mCaptureRequestBuilder.build(), mCaptureCallback, mBackgroundHandler);
    
    mManualFocusEngaged = true;
    }
    
    
    
    
       private boolean isMeteringAreaAFSupported() { // AF stands for AutoFocus
    
        Integer afRegion = mCameraCharacteristics.get(CameraCharacteristics.CONTROL_MAX_REGIONS_AF);
        return afRegion != null && afRegion >= 1;
    
       }
    
    
    private boolean isMeteringAreaAESupported() {//AE stands for AutoExposure
    
        Integer aeState = mCameraCharacteristics.get(CameraCharacteristics.CONTROL_MAX_REGIONS_AE);
        return aeState!=null && aeState >=1;
    
    }
    

    希望它会有所帮助.享受编码

    Hope it helps. Enjoy coding

    这篇关于Android camera2 api touch聚焦示例?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

  • 查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆