在照相机2上使用闪光灯拍照可在发生闪光灯(即无闪光灯)"after"提供照片



我的代码基于Google Camera2 Basic的示例,并添加了始终支持flash。但看起来这张照片是在闪光后拍摄的。即使闪光灯被触发,我(几乎)总是得到未闪光的照片。

修改后的预览请求生成器:

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

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

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

并用修改了process()开关

       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时立即触发捕获来解决这个问题。基本上,如果闪光灯亮了,那么无论你处于什么状态,你都需要立即进行捕捉,因为它只会亮一次。如果自动对焦/曝光等在那一点上没有正确收敛,你就无能为力了。

你可以在onCaptureCompleted开始时这样做检查:

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是在打开相机时从CameraCharacteristics设置的,如下所示:

mFlashAvailable = characteristics.get(CameraCharacteristics.FLASH_INFO_AVAILABLE);

mWaitingForFlash只是一个可以在开始预捕获时设置的标志,这样就不会捕获多个帧。然而,在您的特定情况下,这可能没有必要。

正如你在问题中所描述的,这将在状态收敛之前(即图片在闪光之后)闪光时发生。然而,当闪光灯延迟发射时,你也需要处理这种情况(我从未见过这种情况,只是以防万一)。您可以通过在将CONTROL_AE_MODE设置为CaptureRequest.CONTROL_AE_MODE_ON_ALWAYS_FLASH时设置类似mExpectingFlash = true;的标志来做到这一点,如果是真的,则不以通常的方式进行捕捉(因为您将在检测到闪光状态时进行捕捉)。如果您正在使用CONTROL_AE_MODE_ON_AUTO_FLASH,您也可以在获得aeState == CaptureRequest.CONTROL_AE_STATE_FLASH_REQUIRED时设置此标志。作为一个安全网,我有一个超时时间,这样我就不会等待一个永远不会出现的闪光灯,以防检测到CONTROL_AE_STATE_FLASH_REQUIRED但闪光灯没有启动。

如果你捕捉到多个帧,你可以在检测到闪光时读取时间戳,如下所示:

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

然后将其与onImageAvailable 中图像的时间戳进行交叉检查

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

相关内容

  • 没有找到相关文章

最新更新