相机 2 API 触摸对焦



我浏览了有关触摸聚焦的各种问题,但我找不到"最佳"或"正确"的解决方案。我把一些答案放在一起,并提出了这个实现:

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

构建矩形的管理方式如下:

//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;
}

但它似乎确实工作正常。点击后,相机似乎经常陷入无休止的扫描中。或者它聚焦并在获得焦点时,它会跳回到上一个焦点,图像最终变得模糊。

知道问题可能是什么吗?

当您设置焦点区域时,请使用以下代码,它应该可以工作:

        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);

据我所知,如果您将CONTROL_AF_MODE设置为CONTROL_AF_MODE_CONTINUOUS_PICTURE它会继续尝试聚焦。该模式必须自动开启,但必须触发。所以在这里启动触发器,在你的mSessionCaptureCallback onCaptureCompleted方法应该看起来像这样:

@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);
   }

最新更新