Skip to content Skip to sidebar Skip to footer

Taking Picture With Flash On Camera2 Gives Picture "after" Flash Occured (i.e Without Flash)

I based my code on the sample from Google Camera2-Basic and added flash always support. But It looks like the picture is taken right after the flash has occur. I (almost) always ge

Solution 1:

I had this exact same problem, also on a Nexus 5. I worked around it by checking CaptureResult.FLASH_STATE and triggering a capture immediately if it is equal to CaptureResult.FLASH_STATE_FIRED. Basically, if the flash fires, then you need to do a capture right then and there, regardless of what state you are in, because it's only going to fire once. If the auto-focus/exposure etc hasn't properly converged at that point there's nothing you can do about it.

You can do a check at the start of onCaptureCompleted like this:

if(mFlashAvailable && mWaitingForFlash)
{
     Integer flashState = result.get(CaptureResult.FLASH_STATE);
     if(flashState != null && flashState==CaptureResult.FLASH_STATE_FIRED)
     {
         mWaitingForFlash = false;

         // do the capture...
         mState = STATE_PICTURE_TAKEN;
         captureStillPicture();

         return;  // don't call process()
     }
}

mFlashAvailable is set from the CameraCharacteristics when opening the camera like this:

mFlashAvailable = characteristics.get(CameraCharacteristics.FLASH_INFO_AVAILABLE);

mWaitingForFlash is just a flag you can set when you start the precapture, so that you don't capture more than one frame. This might not be necessary in your particular case however.

That will take care of when the flash fires before the state converges (i.e. the picture is after the flash), as you describe in your question. However you also need to handle the case when the flash is firing late (I've never seen this actually happen but just in case). You can do that by setting a flag like mExpectingFlash = true; when setting the CONTROL_AE_MODE to CaptureRequest.CONTROL_AE_MODE_ON_ALWAYS_FLASH, and not capturing the usual way if it is true (since you will capture when you detect the flash firing state instead). You can also set this flag when you get aeState == CaptureRequest.CONTROL_AE_STATE_FLASH_REQUIRED if you are using CONTROL_AE_MODE_ON_AUTO_FLASH. As a safety net I have a timeout so I don't end up waiting for a flash that never comes in case CONTROL_AE_STATE_FLASH_REQUIRED is detected but the flash doesn't fire.

If you capture multiple frames, you can read the timestamp when you detect the flash firing, like this:

long timestamp = result.get(CaptureResult.SENSOR_TIMESTAMP);

and then cross check it against the timestamp of the image in onImageAvailable

Imageimage= reader.acquireLatestImage();
 if (image != null)
 {
     longtimestamp= image.getTimestamp();
     // ....
 }

Post a Comment for "Taking Picture With Flash On Camera2 Gives Picture "after" Flash Occured (i.e Without Flash)"