Android установил камеру2 фокус только один раз в начале интервальной съемки
Я хочу сделать простое приложение, которое делает снимки для timelapse. Наконец-то я это сделал. Но мне интересно, можно ли заблокировать фокус только один раз, на первом фото? И позже использовать это сохраненное значение о фокусе (если возможно)? Вообще это хорошая идея? Я думал, что каждые несколько секунд звонит lockFocus()
это слишком дорого Пока устройство установлено неподвижно, неподвижно.
На самом деле у меня есть код, как Google пример кода. Я устанавливаю CaptureRequest.Builder
поле CONTROL_AF_TRIGGER
в CONTROL_AF_TRIGGER_START
И в CaptureCallback
Я проверяю CaptureResult.CONTROL_AF_STATE
, если ok
затем сделайте окончательный снимок. Может быть, получить в первом фото то LENS_FOCUS_DISTANCE
а потом как-то установить это значение.
PS: Кроме того, я не показываю предварительный просмотр для пользователя, и вся логика камеры работает в Сервисе и в другом потоке. Также я реализовал ImageReader
и больше.
Мой код:
// before is `CameraManager`, setting outputs, opening camera - all ok
public void makePhoto() { // this I call from outer
// plus some observer, not important conditions for this issue
createCameraPreviewSession();
}
private void createCameraPreviewSession() {
mPreviewRequestBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
mPreviewRequestBuilder.addTarget(previewSurface);
mCameraDevice.createCaptureSession(Arrays.asList(previewSurface, mImageReader.getSurface()), new CameraCaptureSession.StateCallback() {
public void onConfigured(CameraCaptureSession session) {
mCaptureSession = session;
mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);
mPreviewRequest = mPreviewRequestBuilder.build();
startedRepeatedRequest = false; // simple flag to start lockFocus after below request has started, once
mCaptureSession.setRepeatingRequest(mPreviewRequest, mCaptureCallback, null);
}
}
}
private CameraCaptureSession.CaptureCallback mCaptureCallback = new CameraCaptureSession.CaptureCallback() {
public void onCaptureProgressed(CameraCaptureSession session, CaptureRequest request, CaptureResult partialResult) {
process(partialResult);
}
private void process(CaptureResult result) {
if(!startedRepeatedRequest) {
// this is called only once, on the beginning of session
lockFocus();
startedRepeatedRequest = true;
}
switch(mState) {
case STATE_PREVIEW:
break;
case STATE_WAITING_LOCK:
Integer afState = result.get(CaptureResult.CONTROL_AF_STATE);
if (afState == null) {
captureStillPicture();
} else if (CaptureResult.CONTROL_AF_STATE_FOCUSED_LOCKED == afState || CaptureResult.CONTROL_AF_STATE_NOT_FOCUSED_LOCKED == afState) {
Integer aeState = result.get(CaptureResult.CONTROL_AE_STATE);
if (aeState == null || aeState == CaptureResult.CONTROL_AE_STATE_CONVERGED) {
mState = STATE_PICTURE_TAKEN;
captureStillPicture(); // this leads to final capture photo
} else {
runPrecaptureSequence();
}
}
break;
// There are also flags for STATE_PRECAPTURE, and STATE_WAITING_NON_PRECAPTURE but this doesn't matter here
}
}
}
private void lockFocus() {
mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER, CameraMetadata.CONTROL_AF_TRIGGER_START);
mState = STATE_WAITING_LOCK;
mCaptureSession.capture(mPreviewRequestBuilder.build(), mCaptureCallback, null);
}
private void captureStillPicture() {
final CaptureRequest.Builder captureBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE);
Surface surfaceTarget = mImageReader.getSurface();
captureBuilder.addTarget(surfaceTarget);
captureBuilder.set(CaptureRequest.JPEG_QUALITY, (byte) 90);
captureBuilder.set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);
// callback for final capture
CameraCaptureSession.CaptureCallback CaptureCallback = new CameraCaptureSession.CaptureCallback() {
mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER, CameraMetadata.CONTROL_AF_TRIGGER_CANCEL);
mCaptureSession.capture(mPreviewRequestBuilder.build(), mCaptureCallback, null);
mState = STATE_PREVIEW;
session.close();
}
mCaptureSession.stopRepeating();
mCaptureSession.capture(captureBuilder.build(), CaptureCallback, null);
}