在照相机2上用闪光灯拍摄照片时,在“后"拍摄照片.发生闪光(即不闪光) [英] Taking picture with flash on camera2 gives picture "after" flash occured (i.e without flash)

查看:524
本文介绍了在照相机2上用闪光灯拍摄照片时,在“后"拍摄照片.发生闪光(即不闪光)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的代码基于Google Camera2-Basic的示例,并始终支持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 get non flashed picture, even though the flash is triggered.

修改后的预览请求构建器:

The modified preview request builder :

mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_ON_ALWAYS_FLASH);

我还将此控制模式添加到captureStillPicture()

And I also added this control mode to captureStillPicture()

captureBuilder.set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_ON_ALWAYS_FLASH);

并使用以下命令修改了process()开关:

and modified the process() switch with :

       case STATE_WAITING_PRECAPTURE: {
          // CONTROL_AE_STATE can be null on some devices
          Integer aeState = result.get(CaptureResult.CONTROL_AE_STATE);
          Log.i(TAG, "aeState = " + aeState);
          if (aeState == null ||
              aeState == CaptureResult.CONTROL_AE_STATE_PRECAPTURE ||
              aeState == CaptureResult.CONTROL_AE_STATE_CONVERGED ||
              aeState == CaptureRequest.CONTROL_AE_STATE_FLASH_REQUIRED) {
            mState = STATE_WAITING_NON_PRECAPTURE;
          }
          break;
        }

推荐答案

在Nexus 5上,我也遇到了同样的问题.我通过检查CaptureResult.FLASH_STATE并立即触发捕获来解决该问题,如果它等于CaptureResult.FLASH_STATE_FIRED.基本上,如果闪光灯闪光,那么无论您处于什么状态,您都需要在此时和那里进行捕捉,因为它只会闪光一次.如果此时自动对焦/曝光等无法正确收敛,则您无能为力.

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.

您可以像这样在onCaptureCompleted的开头进行检查:

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

像这样打开相机时,可以通过CameraCharacteristics设置

mFlashAvailable:

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

mFlashAvailable = characteristics.get(CameraCharacteristics.FLASH_INFO_AVAILABLE);

mWaitingForFlash只是您在启动预捕获时可以设置的标志,这样就不会捕获多个帧.但是,在您的特定情况下,这可能不是必需的.

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.

正如您在问题中所描述的那样,这将解决状态收敛之前闪光灯何时闪光(即图片在闪光灯之后).但是,您还需要处理闪光灯延迟闪光的情况(我从未见过这种情况确实发生,但以防万一).您可以通过将CONTROL_AE_MODE设置为CaptureRequest.CONTROL_AE_MODE_ON_ALWAYS_FLASH时设置类似mExpectingFlash = true;的标志来实现此目的,并且如果设置为true,则不捕获常规方法(因为当检测到闪光灯闪光状态时将捕获).如果使用的是CONTROL_AE_MODE_ON_AUTO_FLASH,则在获取aeState == CaptureRequest.CONTROL_AE_STATE_FLASH_REQUIRED时也可以设置此标志.作为安全网,我有一个超时时间,所以我不必等待等待检测不到CONTROL_AE_STATE_FLASH_REQUIRED但闪光灯不闪光的闪光灯.

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

,然后根据onImageAvailable

 Image image = reader.acquireLatestImage();
 if (image != null)
 {
     long timestamp = image.getTimestamp();
     // ....
 }

这篇关于在照相机2上用闪光灯拍摄照片时,在“后"拍摄照片.发生闪光(即不闪光)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆