Android摄像头自动对焦与触摸对焦实现

1、自动对焦

  在预览前后设置的param里setFocusMode();为Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO或者Camera.Parameters.FOCUS_MODE_AUTO,建议采用后者。注意调用此方法后,再次调用Camera.autoFocus()会导致对焦失败

  参考此文 http://blog.csdn.net/yanzi1225627/article/details/8577682

 

2、触摸对焦

  触摸对焦在设置焦点前需要先取消先前设置的焦点,

  参考文章 http://stackoverflow.com/a/19272166

    /**
     * On each tap event we will calculate focus area and metering area.
     * <p/>
     * Metering area is slightly larger as it should contain more info for exposure calculation.
     * As it is very easy to over/under expose
     */
    public void focusOnTouch(MotionEvent event) {
        if (camera_ != null) {
            //cancel previous actions
            camera_.cancelAutoFocus();
            Rect focusRect = calculateTapArea(event.getX(), event.getY(), 1f);
            Rect meteringRect = calculateTapArea(event.getX(), event.getY(), 1.5f);

            Camera.Parameters parameters = null;
            try {
                parameters = camera_.getParameters();
            } catch (Exception e) {
                e.printStackTrace();
            }

            // check if parameters are set (handle RuntimeException: getParameters failed (empty parameters))
            if (parameters != null) {
                parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
                    List<Camera.Area> focus = new ArrayList<>();
                    focus.add(new Camera.Area(focusRect, 1000));
                    parameters.setFocusAreas(focus);

                    if (parameters.getMaxNumMeteringAreas() > 0) {
                        List<Camera.Area> metering = new ArrayList<>();
                        metering.add(new Camera.Area(focusRect, 1000));
                        parameters.setMeteringAreas(metering);
                    }
                }

                try {
                    camera_.setParameters(parameters);
                    camera_.autoFocus(new Camera.AutoFocusCallback() {
                        @Override
                        public void onAutoFocus(boolean success, Camera camera) {

                        }
                    });
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }

    private int focusAreaSize = 300;

    /**
     * Convert touch position x:y to {@link Camera.Area} position -1000:-1000 to 1000:1000.
     * <p/>
     * Rotate, scale and translate touch rectangle using matrix configured in
     * {@link SurfaceHolder.Callback#surfaceChanged(android.view.SurfaceHolder, int, int, int)}
     */
    private Rect calculateTapArea(float x, float y, float coefficient) {
        int areaSize = Float.valueOf(focusAreaSize * coefficient).intValue();

        int left = clamp((int) x - areaSize / 2, 0, surfaceView_.getWidth() - areaSize);
        int top = clamp((int) y - areaSize / 2, 0, surfaceView_.getHeight() - areaSize);

        RectF rectF = new RectF(left, top, left + areaSize, top + areaSize);
        (new Matrix()).mapRect(rectF);

        return new Rect(Math.round(rectF.left), Math.round(rectF.top), Math.round(rectF.right), Math.round(rectF.bottom));
    }

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

  

posted @ 2016-05-21 17:01  Rison13  阅读(7159)  评论(0编辑  收藏  举报