camera 自动对焦&手动对焦

基础内容可参考

自动对焦系统概述|Camera

https://jingyan.baidu.com/article/22a299b5c882a29e19376aad.html

对焦框坐标基本概念:

Android Camera2之 手动点击区域对焦 - 简书

Camera2点击对焦实现 - mydddfly - 博客园

本文主要总结自己开发过程中遇到的各个知识点

需求: Camera2  App开发:取消自动对焦,设置为触摸手动对焦,对焦完成后依然不允许自动对焦

思路:

触摸屏幕OnTouchListener监听--》根据坐标转换,计算对焦区域--》进行对焦--》显示对焦框

1、触摸屏幕,

private View.OnTouchListener mOntouchListener = new View.OnTouchListener() {
        @Override
        public boolean onTouch(View view, MotionEvent event) {
            try {
                switch(event.getAction()){
                    case MotionEvent.ACTION_DOWN:
                        int[] location = new int[2];
                        mTextureView[0].getLocationOnScreen(location);

                        int tmpx = mTextureView[0].getWidth();
                        int tmpy = mTextureView[0].getHeight();
                        Log.d(TAG, "onTouch,TextureView.getWidth:" + tmpx +
                                ",TextureView.getHeight:" + tmpy + ",location[0]:" + location[0] +
                                ",location[1]" + location[1] + ",TextureView.getLeft:" + mTextureView[0].getLeft()
                                + ",TextureView.getTop:" + mTextureView[0].getTop()+", mTextureView[0].getRight():"+ mTextureView[0].getRight()+", mTextureView[0].getBottom():"+ mTextureView[0].getBottom());

                        int focusWidth = mAutoFoucView.getLayoutParams().width;
                        int focusHeight = mAutoFoucView.getLayoutParams().height;

                        float x_raw = event.getRawX();//between screen
                        float y_raw = event.getRawY();//between screen

                        mAutoFoucView.setVisibility(View.VISIBLE);
                        ViewGroup.MarginLayoutParams layoutParams = (ViewGroup.MarginLayoutParams) mAutoFoucView.getLayoutParams();
//                        int left = (int) (event.getX() - focusWidth / 2 + location[0]);
//                        int top = (int) (event.getY() - focusHeight / 2 + location[1]);
                        int left = (int) (event.getX() - focusWidth / 2);
                        int top = (int) (event.getY() - focusHeight / 2);


                        Log.d(TAG, "onTouch,focusWidth:" + focusWidth +
                                ",focusHeight:" + focusHeight + ",event.getX():" + event.getX() +
                                ",event.getY():" + event.getY() + ",event.getRawX():" + event.getRawX()
                                + ",event.getRawY():" + event.getRawY());

                        layoutParams.leftMargin = left;
                        layoutParams.topMargin = top;
                        mAutoFoucView.setLayoutParams(layoutParams);
                        mAutoFoucView.prepareFocus();

                        int width = mTextureView[0].getWidth();
                        int height = mTextureView[0].getHeight();

                        meteringRectangle = getMeteringRectangles(event.getX(), event.getY(), width, height);

                        Message msg = Message.obtain();
                        msg.what = CameraOpt.MSG_SET_TOUCH_POINT_VALUE;
                        msg.obj= meteringRectangle;
                        msg.arg1 = mAutoFoucView.isFocusing()? 1 : 0;
                        mCameraOpt[0].getHandler().sendMessage(msg);
                        break;
                }
                return true;
            } catch (Exception e) {
                Log.v("onTouch", e.toString());
                return false;
            }

        }


    };
                case MSG_SET_TOUCH_POINT_VALUE:
                    meteringRectangle =(MeteringRectangle[]) msg.obj;
                    isFocusing = msg.arg1 != 0;
                    //Log.i(TAG,"isFocusing="+isFocusing);
                    onTouchFoucs(meteringRectangle);

                    break;
    private void onTouchFoucs(MeteringRectangle[] meteringRectangle) {
        if(isFocusing)
        {
//设置AF/AE对焦区域,开始对焦
            mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_REGIONS, meteringRectangle);
            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_REGIONS, meteringRectangle);
            //        mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_ON);

            mPreviewRequest = mPreviewRequestBuilder.build();
            try {
                mCaptureSession.setRepeatingRequest(mPreviewRequest, mPreviewListener, mHandler);
            } catch (CameraAccessException e) {
                Log.e(TAG, "setRepeatingRequest failed, " + e.getMessage());
            }

        }
    }
private final CameraCaptureSession.CaptureCallback mPreviewListener = new CameraCaptureSession.CaptureCallback() {
        @Override
        public void onCaptureCompleted(CameraCaptureSession session, CaptureRequest request, TotalCaptureResult result) {
            Log.d(TAG, "onCaptureCompleted begin isFocusing="+isFocusing);
            if (mPreviewRequestBuilder == null) {
                return;
            }
            if(isFocusing){
                Integer afState = result.get(CaptureResult.CONTROL_AF_STATE);//
                Log.d(TAG, "onCaptureCompleted begin afState="+afState);
                if (CaptureResult.CONTROL_AF_STATE_FOCUSED_LOCKED == afState
                        || CaptureResult.CONTROL_AF_STATE_NOT_FOCUSED_LOCKED == afState) {

                    isFocusSucess = true;
                    mCamLister.onFocusState(isFocusSucess);

                    mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER, CameraMetadata.CONTROL_AF_TRIGGER_CANCEL);
                    //如果对焦完成后不允许自动对焦,注释掉如下几行。
//                    mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER, CaptureRequest.CONTROL_AF_TRIGGER_IDLE);
//                    mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);
//                    mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_ON);


                    mPreviewRequest = mPreviewRequestBuilder.build();
                    try {
                        mCaptureSession.setRepeatingRequest(mPreviewRequest, null, mHandler);//
                    } catch (CameraAccessException e) {
                        Log.e(TAG, "setRepeatingRequest failed, errMsg: " + e.getMessage());
                    }

                }
                else {
                    isFocusSucess = false;
                    mCamLister.onFocusState(isFocusSucess);
                }
            }

            isFocusing = false;
    super.onCaptureCompleted(session, request, result);
//            Log.d(TAG, mCameraId + " onCaptureCompleted end");
        }
        @Override
        public void onCaptureStarted(CameraCaptureSession session, CaptureRequest request, long timestamp, long frameNumber) {
            super.onCaptureStarted(session, request, timestamp, frameNumber);
        }

        @Override
        public void onCaptureFailed(CameraCaptureSession session, CaptureRequest request, CaptureFailure failure) {
            super.onCaptureFailed(session, request, failure);
        }
    };

mPreviewListener是监听预览界面;

getMeteringRectangles函数后面补充

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值