What's the correct way to implement Tap To Focus for camera?

前端 未结 5 1592
难免孤独
难免孤独 2021-01-30 10:59

I\'m working on an app which has a custom camera screen, for which I\'m supposed to implement tap to focus, like in the Android(more specifically, the Galaxy S4) camera app.

5条回答
  •  情书的邮戳
    2021-01-30 11:41

    this has the solution. I just added the implementation of some missing methods in his code.

    private static  final int FOCUS_AREA_SIZE= 300;
    

    //

    mCameraPreview.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                if (event.getAction() == MotionEvent.ACTION_DOWN) {
                    focusOnTouch(event);
                }
                return true;
            }
        });
    

    //

     private void focusOnTouch(MotionEvent event) {
        if (mCamera != null ) {
    
            Camera.Parameters parameters = mCamera.getParameters();
            if (parameters.getMaxNumMeteringAreas() > 0){
                Log.i(TAG,"fancy !");
                Rect rect = calculateFocusArea(event.getX(), event.getY());
    
                parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);
                List meteringAreas = new ArrayList();
                meteringAreas.add(new Camera.Area(rect, 800));
                parameters.setFocusAreas(meteringAreas);
    
                mCamera.setParameters(parameters);
                mCamera.autoFocus(mAutoFocusTakePictureCallback);
            }else {
                mCamera.autoFocus(mAutoFocusTakePictureCallback);
            }
        }
    }
    
    private Rect calculateFocusArea(float x, float y) {
        int left = clamp(Float.valueOf((x / mCameraPreview.getWidth()) * 2000 - 1000).intValue(), FOCUS_AREA_SIZE);
        int top = clamp(Float.valueOf((y / mCameraPreview.getHeight()) * 2000 - 1000).intValue(), FOCUS_AREA_SIZE);
    
        return new Rect(left, top, left + FOCUS_AREA_SIZE, top + FOCUS_AREA_SIZE);
    }
    
    private int clamp(int touchCoordinateInCameraReper, int focusAreaSize) {
        int result;
        if (Math.abs(touchCoordinateInCameraReper)+focusAreaSize/2>1000){
            if (touchCoordinateInCameraReper>0){
                result = 1000 - focusAreaSize/2;
            } else {
                result = -1000 + focusAreaSize/2;
            }
        } else{
             result = touchCoordinateInCameraReper - focusAreaSize/2;
        }
        return result;
    }
    

    // implement this callback to trigger the focus.

    private Camera.AutoFocusCallback mAutoFocusTakePictureCallback = new Camera.AutoFocusCallback() {
            @Override
            public void onAutoFocus(boolean success, Camera camera) {
                if (success) {
                    // do something...
                    Log.i("tap_to_focus","success!");
                } else {
                    // do something...
                    Log.i("tap_to_focus","fail!");
                }
            }
        };
    

提交回复
热议问题