实现Tap To Focus相机的正确方法是什么?

时间:2013-08-01 12:13:28

标签: android android-camera

我正在开发一款具有自定义相机屏幕的应用程序,我应该实现点按以对焦,就像Android(更具体地说,Galaxy S4)相机应用程序一样。

我已尝试使用here概述的步骤,但似乎没有引起任何明显的关注。对焦模式设置为连续图片(我们仅支持特定设备)。

当用户点击相机预览时,我需要关注图像的上半部分。为此,我使用代码片段

Parameters parameters = mCamera.getParameters();

if (parameters.getMaxNumFocusAreas() > 0) {

    ArrayList<Area> focusAreas = new ArrayList<Camera.Area>(1);
    focusAreas.add(new Area(new Rect(-1000, -1000, 1000, 0), 750));

    parameters.setFocusAreas(focusAreas);
    mCamera.setParameters(parameters);
}

我不想要自动聚焦,因为聚焦图像需要很长时间。我只对图像的上半部分感兴趣。有没有人成功实现了Tap to Focus和连续图片模式?

5 个答案:

答案 0 :(得分:25)

最近陷入了这个问题。正如MatheusJardimB所说,this question有很多帮助。

但是,在我的情况下,我想以ContinuousPicture模式开始,然后可以点按以进行对焦,然后继续使用ContinuousPicture模式。

我设法使用onAutoFocus的{​​{1}}方法让它工作。我不确定它是最好还是最漂亮的方式,但它似乎有效。

以下是代码:

Camera.AutoFocusCallback()

您可以将焦点区域更改为

setOnTouchListener(new View.OnTouchListener() {         
    @Override
        public boolean onTouch(View v, MotionEvent event) {
            if (mCamera != null) {
                Camera camera = mCamera.getCamera();
                camera.cancelAutoFocus();
                Rect focusRect = calculateTapArea(event.getX(), event.getY(), 1f);

                Parameters parameters = camera.getParameters();
                parameters.setFocusMode(Parameters.FOCUS_MODE_MACRO);

                if (parameters.getMaxNumFocusAreas() > 0) {
                    List<Area> mylist = new ArrayList<Area>();
                    mylist.add(new Camera.Area(focusRect, 1000));
                    parameters.setFocusAreas(mylist);
                }

                camera.setParameters(parameters);
                camera.autoFocus(new Camera.AutoFocusCallback() {                   
                    @Override
                    public void onAutoFocus(boolean success, Camera camera) {
                        camera.cancelAutoFocus();
                        Parameters params = camera.getParameters();
                        if (!params.getFocusMode().equals(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE)) {
                            params.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);
                            camera.setParameters(params);
                        }
                    }
                });
            }
            return true;
        }
        return false;
    });

它应该有用。

<强>更新

我最近收购了三星S5并对其进行了测试。它没有那么好用,所以我添加了一些修改,它现在正在工作。这也在Galaxy S6和Galaxy Note4上成功测试过。

以下是修改过的代码:

ArrayList<Area> focusAreas = new ArrayList<Camera.Area>(1);
focusAreas.add(new Area(new Rect(-1000, -1000, 1000, 0), 750));

答案 1 :(得分:18)

this有解决方案。我刚刚在他的代码中添加了一些缺少方法的实现。

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<Camera.Area> meteringAreas = new ArrayList<Camera.Area>();
            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;
}

//实现此回调以触发焦点。

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!");
            }
        }
    };

答案 2 :(得分:2)

One of the other answers会让您的相机丢弃先前给定的对焦点并返回到我认为没有意义的连续对焦。

另外,如果您查看帖子中的链接,原始答案将使用parameters.setFocusMode(Parameters.FOCUS_MODE_AUTO);

我用这行代码实现了上面的代码而不是连续焦点,它似乎工作得更好。

答案 3 :(得分:0)

 binding.cPreview.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            mCamera.autoFocus(myAutoFocusCallback);
        }
    });


 Camera.AutoFocusCallback myAutoFocusCallback = new Camera.AutoFocusCallback(){

        @Override
        public void onAutoFocus(boolean arg0, Camera arg1) {
            // TODO Auto-generated method stub
        }};

答案 4 :(得分:-1)

我有同样的问题。 我在很多设备和许多Android版本上都检查了这个。

焦点区域似乎无法在连续对焦模式下工作

我的解决方法是将焦点模式设置为AUTO或MACRO以及设置焦点区域:

params.setFocusMode(Camera.Parameters.FOCUS_MODE_MACRO);
params.setFocusAreas(focusAreas);
mCamera.setParameters(params);

请注意Galaxy S3上的相机应用程序&amp; S4的工作方式相同:它永久处于连续模式。当您触摸屏幕时,它会切换到自动&amp;设置焦点区域。但过了一会儿,它又回到了连续模式,焦点区域又回到了屏幕的中心。

我希望这能以某种方式帮助你。