Android手机上实现自动聚焦和自动感光功能

首先是基于前一篇文章:

https://blog.csdn.net/zhangkai19890929/article/details/88305440

另外聚焦和聚光的理论要参考这篇文章:
https://blog.csdn.net/gh8609123/article/details/67633093

所以要结合2篇文章来看.

所谓自动聚焦,意思很明白,就是让摄像头聚焦在手指触摸的范围内,让这个范围内的图像信息看的更清晰.
所谓自动聚光,就是手机触摸的范围内,光线更充足.

另外,上面的功能,还需要同时支持前置和后置.

关于前置,绝大部分的前置镜头不支持自动聚焦,只支持自动聚光.

point是你自己触摸时候屏幕上的位置坐标信息,在第一篇文章中有介绍.

  public void onFocus(Point point,int width ,int height , Camera.AutoFocusCallback callback){

        if(mCamera == null) return ;

//        Camera.Parameters parameters=mCamera.getParameters();
//        Camera.Size previewSize = parameters.getPreviewSize();
//
//        if (parameters.getMaxNumFocusAreas() > 0) {
//            Log.e(TAG," support auto focus");
//            mCamera.cancelAutoFocus();
//            List areas=new ArrayList();
//            Rect focusRect = calculateTapArea(point.x, point.y, 1.0f, previewSize , width,height);
//            areas.add(new Camera.Area(focusRect, 1000));
////            parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);
//            parameters.setFocusAreas(areas);
//            mCamera.autoFocus(callback);
//        }
//
//        if(parameters.getMaxNumMeteringAreas() > 0)
//        {
//            Log.e(TAG," support meter areas");
//            List areasMetrix=new ArrayList();
//            Rect metrixRect = calculateTapArea(point.x, point.y, 1.0f, previewSize , width ,height);
//            areasMetrix.add(new Camera.Area(metrixRect,1000));
//            parameters.setMeteringAreas(areasMetrix);
//        }
//
//        //public 模块
//        parameters.setAutoWhiteBalanceLock(true);
//        parameters.setAutoExposureLock(true);
//        try {
//            mCamera.setParameters(parameters);
//        } catch (Exception e) {
//            // TODO: handle exception
//            e.printStackTrace();
//        }

        Rect focusRect = calculateTapArea(point.x, point.y, 1f, width, height);
        Rect meteringRect = calculateTapArea(point.x, point.y, 1.5f, width, height);

        mCamera.cancelAutoFocus();
        Camera.Parameters params = mCamera.getParameters();
        final String currentFocusMode = params.getFocusMode();
        if(params.getMaxNumFocusAreas() > 0)
        {
            params.setFocusMode(Camera.Parameters.FOCUS_MODE_MACRO);
            List focusAreas = new ArrayList<>();
            focusAreas.add(new Camera.Area(focusRect, 800));
            params.setFocusAreas(focusAreas);
        }
        else
        {
            Log.e(TAG,"camera do not support focus areas ");
        }

        if (params.getMaxNumMeteringAreas() > 0) {
            List meteringAreas = new ArrayList<>();
            meteringAreas.add(new Camera.Area(meteringRect, 1000));
            params.setMeteringAreas(meteringAreas);
        } else {
            Log.e(TAG, "metering areas not supported");
        }

        try {
            mCamera.setParameters(params);
        }catch (Exception e)
        {
            Log.e(TAG,"Set params Faild:"+e.getMessage() );
        }

        mCamera.autoFocus(new Camera.AutoFocusCallback() {
            @Override
            public void onAutoFocus(boolean success, Camera camera) {
                Camera.Parameters params = camera.getParameters();
                params.setFocusMode(currentFocusMode);
                camera.setParameters(params);
            }
        });
    }

    private static Rect calculateTapArea(float x, float y, float coefficient, int width, int height) {
        float focusAreaSize = 300;
        int areaSize = Float.valueOf(focusAreaSize * coefficient).intValue();
        int centerX = (int) (x / width * 2000 - 1000);
        int centerY = (int) (y / height * 2000 - 1000);

        int halfAreaSize = areaSize / 2;
        RectF rectF = new RectF(clamp(centerX - halfAreaSize, -1000, 1000)
                , clamp(centerY - halfAreaSize, -1000, 1000)
                , clamp(centerX + halfAreaSize, -1000, 1000)
                , clamp(centerY + halfAreaSize, -1000, 1000));
        Log.e(TAG,"left:" + Math.round(rectF.left) + " -- top:" + Math.round(rectF.top) + " -- right:" + Math.round(rectF.right) + " -- bottom:"+ Math.round(rectF.bottom) );
        return new Rect(Math.round(rectF.left), Math.round(rectF.top), Math.round(rectF.right), Math.round(rectF.bottom));
    }

    private static int clamp(int x, int min, int max) {
        if (x > max) {
            return max;
        }
        if (x < min) {
            return min;
        }
        return x;
    }

你可能感兴趣的:(知识库)