我浏览了有关触摸聚焦的各种问题,但我找不到“最佳”或“正确”的解决方案。我将一些答案放在一起并提出了这个实现:
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);
}
我是一名优秀的程序员,十分优秀!