在相机 2 上使用闪光灯拍照会在“发生”闪光灯后(即没有闪光灯)给出照片
Posted
技术标签:
【中文标题】在相机 2 上使用闪光灯拍照会在“发生”闪光灯后(即没有闪光灯)给出照片【英文标题】:Taking picture with flash on camera2 gives picture "after" flash occured (i.e without flash) 【发布时间】:2016-02-26 23:14:45 【问题描述】:我的代码基于 Google Camera2-Basic 的示例,并添加了始终支持闪光灯。但看起来照片是在闪光发生后立即拍摄的。即使触发了闪光灯,我(几乎)总是得到不闪光的图片。
修改后的预览请求生成器:
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;
【问题讨论】:
您尝试了哪种设备? 谢谢!我从未对 Nexus5 上的 camera2 实施质量印象深刻。 嗯,我认为这在我的实现中更多是一个问题,但我不知道是什么:( FWIW,您的代码与Google's Camera2Basic code 不太一致。CONVERGED
在 STATE_WAITING_LOCK
那里处理。
是的,我添加了这种情况,因为我想要打开或关闭闪光灯模式。不是 flash_auto。根据这篇文章,这是要走的路:***.com/a/24664959/1532108
【参考方案1】:
我在 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();
// ....
【讨论】:
非常感谢您的回答,我会试一试并告诉您。以上是关于在相机 2 上使用闪光灯拍照会在“发生”闪光灯后(即没有闪光灯)给出照片的主要内容,如果未能解决你的问题,请参考以下文章