Android9.0 Camera App代码跟踪之对焦

各位早安

接着上个博客,今天继续跟踪代码.

在我跟踪代码的时候脑子里一直有个疑问,相机是怎么对焦的?今天就带着这个疑问来跟踪下代码解开心中的疑问.

第一步,先看下进入预览后相机是怎么启动对焦的

打开PhotoModule.java搜索关键字Focus

//这里需要给Camera Parameters传递一个FocusArea对象,代码对焦区域
private void setFocusAreasIfSupported() {
        if (mFocusAreaSupported) {
            mParameters.setFocusAreas(mFocusManager.getFocusAreas());
        }
    }

//FocusAreas对象在FocusOverlayManager里面创建
@TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH)
    private void initializeMeteringAreas(int x, int y) {
        if (mMeteringArea == null) {
            mMeteringArea = new ArrayList<Object>();
            mMeteringArea.add(new Area(new Rect(), 1));
        }

        // Convert the coordinates to driver format.
        // AE area is bigger because exposure is sensitive and
        // easy to over- or underexposure if area is too small.
        calculateTapArea(x, y, 1.5f, ((Area) mMeteringArea.get(0)).rect);
    }

//设置CameraParameters
// We separate the parameters into several subsets, so we can update only
    // the subsets actually need updating. The PREFERENCE set needs extra
    // locking because the preference can be changed from GLThread as well.
    private void setCameraParameters(int updateSet) {
        if (mCameraDevice == null) {
            return;
        }
        synchronized (mCameraDevice) {
            boolean doModeSwitch = false;

            if ((updateSet & UPDATE_PARAM_INITIALIZE) != 0) {
                updateCameraParametersInitialize();
            }

            if ((updateSet & UPDATE_PARAM_ZOOM) != 0) {
                updateCameraParametersZoom();
            }

            if ((updateSet & UPDATE_PARAM_PREFERENCE) != 0) {
                doModeSwitch = updateCameraParametersPreference();
            }

            mCameraDevice.setParameters(mParameters);

            // Switch to gcam module if HDR+ was selected
            if (doModeSwitch && !mIsImageCaptureIntent) {
                mHandler.sendEmptyMessage(SWITCH_TO_GCAM_MODULE);
            }
        }
    }

当预览界面被点击的时候会调用onSingleTapUp方法

 // Preview area is touched. Handle touch focus.
    @Override
    public void onSingleTapUp(View view, int x, int y) {
        if (mPaused || mCameraDevice == null || !mFirstTimeInitialized
                || mCameraState == SNAPSHOT_IN_PROGRESS
                || mCameraState == SWITCHING_CAMERA
                || mCameraState == PREVIEW_STOPPED) {
            return;
        }
        //If Touch AF/AEC is disabled in UI, return
        if(this.mTouchAfAecFlag == false) {
            return;
        }
        // Check if metering area or focus area is supported.
        if (!mFocusAreaSupported && !mMeteringAreaSupported) return;
        if (! mFocusManager.getPreviewRect().contains(x, y)) return;
        mFocusManager.onSingleTapUp(x, y);
    }

//FocusOverlayManager类中的方法
public void onSingleTapUp(int x, int y) {
        if (!mInitialized || mState == STATE_FOCUSING_SNAP_ON_FINISH) return;

        UsageStatistics.onEvent(UsageStatistics.COMPONENT_CAMERA,
                UsageStatistics.ACTION_TOUCH_FOCUS, x + "," + y);

        // Let users be able to cancel previous touch focus.
        if ((mState == STATE_FOCUSING ||
                    mState == STATE_SUCCESS || mState == STATE_FAIL)) {
            cancelAutoFocus();
        }
        if (mPreviewRect.width() == 0 || mPreviewRect.height() == 0) return;
        // Initialize variables.
        // Initialize mFocusArea.
        if (mFocusAreaSupported) {
            initializeFocusAreas(x, y);
        }
        // Initialize mMeteringArea.
        if (mMeteringAreaSupported) {
            initializeMeteringAreas(x, y);
        }

        // Use margin to set the focus indicator to the touched area.
        mUI.setFocusPosition(x, y);

        if (mZslEnabled) {
            mTouchAFRunning = true;
        }

        // Stop face detection because we want to specify focus and metering area.
        mListener.stopFaceDetection();

        // Set the focus area and metering area.
        mListener.setFocusParameters();//此处会更新Camera的参数,将新的对焦区域传给Camera
        if (mFocusAreaSupported) {
            autoFocus();
        } else {  // Just show the indicator in all other cases.
            updateFocusUI();
            // Reset the metering area in 3 seconds.
            mHandler.removeMessages(RESET_TOUCH_FOCUS);
            mHandler.sendEmptyMessageDelayed(RESET_TOUCH_FOCUS, RESET_TOUCH_FOCUS_DELAY);
        }
    }

这样Camera的参数被更新后预览界面就会刷新,就可以看到对焦成功的效果了.

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值