简体   繁体   English

Camera2 API Touch to Focus

[英]Camera2 API Touch to Focus

i looked through the various questions concerning touch to focus, but i could not find the "best" or "right" solution. 我查看了有关触摸的各种问题,但我无法找到“最佳”或“正确”的解决方案。 I put some answers together and came up with this implementation: 我把一些答案放在一起,并提出了这个实现:

mTextureView.setOnTouchListener(new View.OnTouchListener() {
    @Override
    public boolean onTouch(View view, MotionEvent motionEvent) {
        float positionX = (int) motionEvent.getX();
        float positionY = (int) motionEvent.getY();

        //Build the Rectangle, where the focus should be applied.
        Rect focusRect = calculateFocusRect(motionEvent.getX(), motionEvent.getY());
        MeteringRectangle meteringRectangle = new MeteringRectangle(focusRect, 500);
        final MeteringRectangle[] meterRecArray = { meteringRectangle };

        mPreviewCaptureRequestBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER, CaptureRequest.CONTROL_AF_TRIGGER_CANCEL);

        //Set a captureRequest to cancel focus.
        try {
            mCameraCaptureSession.capture(mPreviewCaptureRequestBuilder.build(), mSessionCaptureCallback, mBackgroundHandler);
            mState = STATE_PREVIEW;
        } catch (CameraAccessException e) {
            e.printStackTrace();
        }

        //Set the focusRegion.
        mPreviewCaptureRequestBuilder.set(CaptureRequest.CONTROL_AF_REGIONS, meterRecArray);
        mPreviewCaptureRequestBuilder.set(CaptureRequest.CONTROL_AE_REGIONS, meterRecArray);
        mPreviewCaptureRequestBuilder.set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);

        //Restart the Preview, so changes apply.
        try {
            mCameraCaptureSession.abortCaptures();
            mCameraCaptureSession.setRepeatingRequest(mPreviewCaptureRequestBuilder.build(), mSessionCaptureCallback, mBackgroundHandler);
        } catch (CameraAccessException e) {
            Log.e("Camera", "RepeatingRequest Failed");
            e.printStackTrace();
        }

        return false;
    }
});

Building the Rectangle is managed like this: 构建Rectangle的方式如下:

//Calculate a Rectangle, where the user touched the screen.
private MeteringRectangle[] calculateFocusRect(float x, float y) {
    //Size of the Rectangle.
    int areaSize = 200;

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

    RectF rectF = new RectF(left, top, left + areaSize, top + areaSize);
    Rect focusRect = new Rect(Math.round(rectF.left), Math.round(rectF.top), Math.round(rectF.right), Math.round(rectF.bottom));
    MeteringRectangle meteringRectangle = new MeteringRectangle(focusRect, 1);

    return new MeteringRectangle[] {meteringRectangle};
}

//Clamp the inputs.
private int clamp(int x, int min, int max) {
    if (x > max) {
        return max;
    }
    if (x < min) {
        return min;
    }
    return x;
}

But it just doesent seem to work right. 但它只是似乎正常工作。 After tapping, the camera often seems to get stuck in an endless scan. 点击后,相机通常似乎陷入无尽的扫描。 Or it focuses and right as it gets the focus, it jumps back to the previous focus and the image ends up blurry. 或者它聚焦并且正确,因为它获得焦点,它跳回到前一个焦点,图像最终模糊。

Any idea what the problem might be? 知道问题可能是什么?

When you set the focus region,use the below code and it should work: 设置焦点区域时,使用下面的代码,它应该工作:

        mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_MODE,CaptureRequest.CONTROL_AF_MODE_AUTO);
        mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER,CaptureRequest.CONTROL_AF_TRIGGER_START);
        mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AE_MODE,CaptureRequest.CONTROL_AE_MODE_ON);

As far as I know, if you set the CONTROL_AF_MODE to CONTROL_AF_MODE_CONTINUOUS_PICTURE it will keep trying to focus. 据我所知,如果你将CONTROL_AF_MODE设置为CONTROL_AF_MODE_CONTINUOUS_PICTURE ,它将继续尝试聚焦。 The mode has to be on auto but it has to be triggered. 模式必须是自动,但必须触发。 So start the trigger here and in your mSessionCaptureCallback 's onCaptureCompleted method should look something like this: 所以在这里启动触发器并在你的mSessionCaptureCallbackonCaptureCompleted方法中应该看起来像这样:

@Override
public void onCaptureCompleted(@NonNull CameraCaptureSession session, @NonNull 
                               CaptureRequest request,
                               @NonNull TotalCaptureResult result) {
    super.onCaptureCompleted(session, request, result);
    mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER,
                               CaptureRequest.CONTROL_AF_TRIGGER_IDLE);
    mCaptureSession.setRepeatingRequest(mPreviewRequestBuilder.build(),null,null);
   }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM