i am making camera app in that i am showing preview and then there is two option auto focus and second manual seekbar to adjust focus, new here is my problem when i press capture i have to capture 10 image with diffrent value of ISO.I have added loop with counter to capture 10 image with value adjusted after first image it is losing focus and rest of my image are getting blur and out of focus ho can i lock focus in case user chooses auto focus because in manual i am just feeding value during capture but in case of auto focus how can i lock focus , for all 10 image
Unfortunately, I'm unable to share my code, but I'd greatly appreciate any general guidance or examples you could provide to help me address this challenge. Thank you for your assistance!
when user touch on preview i am calling
public void autoFocus() {
try {
focusSeekBar.setCurrentValue(0);
setFocusMode(Mode.AUTO);
mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);
Log.v(TAG, "autoFocus()");
mCaptureSession.setRepeatingRequest(mPreviewRequestBuilder.build(), mCaptureCallback, null);
// set seekbar to focus distance
} catch (CameraAccessException e) {
OnCameraErrorListener.handle(mCameraErrorCallback, e);
}
}
this is during capture process i have one flag when user press auto focus i am setting focused to true
if (focusMode == Mode.MANUAL) {
captureBuilder.set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_OFF);
captureBuilder.set(CaptureRequest.LENS_FOCUS_DISTANCE, focusDistance);
} else if (focusMode == Mode.AUTO && !focused) {
captureBuilder.set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);
}
Basically, what you want to do is get the AF state to be in FOCUSED_LOCKED.
And as the documentation says, you need to do an explicit AF trigger which is done by setting the CaptureRequest#CONTROL_AF_TRIGGER to CONTROL_AF_TRIGGER_START. (Note that the CONTROL_AF_TRIGGER
value should be set in a non-repeating request, not a repeating capture request, to avoid triggering repeatedly)
So your capture process should be something like the following:
CONTROL_AF_TRIGGER_START
.FOCUSED_LOCKED
(or NOT_FOCUSED_LOCKED
in case it fails) in the repeating capture request callback.CONTROL_AF_TRIGGER_CANCEL
so that AF is no longer locked.void preCapture() {
startAfTrigger(); // triggers AF which will eventually lead to locking the lens
awaitFocusLock(); // wait for the locking to be completed
invokeMainCapture(); // this is where you do the 10 captures you were originally doing
cancelAfTrigger(); // release the lens lock
}
void startAfTrigger() {
requestBuilder.set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE); // keeping the same as in repeating request
requestBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER, CameraMetadata.CONTROL_AF_TRIGGER_START); // explicit AF trigger start
mCaptureSession.capture(requestBuilder.build(), captureCallback, null); // non-repeating request
// waits until the capture request has been processed by framework, basically wait until CaptureCallback#onCaptureCompleted is called once
captureCallback.await();
}
void awaitFocusLock() {
// waits until the capture request has a CaptureResult that satisfies the condition in CaptureResultVerifier#isVerified()
mCaptureCallback.await(new CaptureResultVerifier { // the mCaptureCallback should be the callback instance set for repeating request
boolean isVerified(TotalCaptureResult captureResult) {
int afState = captureResult.get(CaptureResult.CONTROL_AF_STATE);
return afState == CameraMetadata.CONTROL_AF_STATE_FOCUSED_LOCKED || // lens locked and focus succeeded
afState == CameraMetadata.CONTROL_AF_STATE_NOT_FOCUSED_LOCKED; // lens locked, but failed to get good focus
}
})
}
void cancelAfTrigger() {
requestBuilder.set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE); // keeping the same as in repeating request
requestBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER, CameraMetadata.CONTROL_AF_TRIGGER_CANCEL);
mCaptureSession.capture(requestBuilder.build(), captureCallback, null); // non-repeating request
// waits until the capture request has been processed by framework, basically wait until CaptureCallback#onCaptureCompleted is called once
captureCallback.await();
}
For more details on the AF state and related transitions, take a look at https://source.android.com/docs/core/camera/camera3_3Amodes#af-state too.