相机2 api触发闪光灯/无闪光灯图像时出现问题



我会解释我的情况。 我正在尝试做一个应用程序,其中每 5 秒拍摄一张图像,一张没有闪光灯,然后在 5 秒后一张带闪光灯,每次都重复此操作。所以需要一个没有闪光灯,一个有闪光灯,一个没有闪光灯,一个有闪光灯......无限。

情况是,使用我的代码,我可以在某些设备上执行此操作,但相同的代码将无法像我想要的那样在其他设备上工作。 即:

  • BQ Aquaris X5 Plus:无闪光灯图像是正确的,但闪光灯图像将只是白色。
  • BQ 水瓶座 E5: 不会触发闪光灯。

这怎么可能,我尝试过的所有设备都是 Camera2 API 的旧版硬件支持级别。

这是我代码中的一些重要方法(由于字符限制,我无法发布所有代码)。我从谷歌的例子开始:

这个设置自动闪光执行上述操作。

private void setAutoFlash(CaptureRequest.Builder requestBuilder) {
if (mFlashSupported) {
if(phototaken) {
requestBuilder.set(CaptureRequest.CONTROL_AE_MODE,CaptureRequest.CONTROL_AE_MODE_ON_AUTO_FLASH);
requestBuilder.set(CaptureRequest.FLASH_MODE, CaptureRequest.FLASH_MODE_OFF);
}else{
requestBuilder.set(CaptureRequest.FLASH_MODE, CaptureRequest.FLASH_MODE_SINGLE);
}
}
}

另一个适用于某些设备和bq aquaris e5,但在bq aquaris x5 plus中不会触发闪光灯。

private void setAutoFlash(CaptureRequest.Builder requestBuilder) {
if (mFlashSupported) {
if(phototaken) {
requestBuilder.set(CaptureRequest.CONTROL_AE_MODE,CaptureRequest.CONTROL_AE_MODE_ON_AUTO_FLASH);
requestBuilder.set(CaptureRequest.FLASH_MODE, CaptureRequest.FLASH_MODE_OFF);
}else{
requestBuilder.set(CaptureRequest.CONTROL_AE_MODE,CaptureRequest.CONTROL_AE_MODE_ON_ALWAYS_FLASH);
requestBuilder.set(CaptureRequest.FLASH_MODE, CaptureRequest.FLASH_MODE_OFF);
}
}
}

还有我的截图剧照

private void captureStillPicture() {
try {
final Activity activity = getActivity();
if (null == activity || null == mCameraDevice) {
return;
}
// This is the CaptureRequest.Builder that we use to take a picture.
final CaptureRequest.Builder captureBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE);
captureBuilder.addTarget(mImageReader.getSurface());
// Use the same AE and AF modes as the preview.
captureBuilder.set(CaptureRequest.CONTROL_AF_MODE,
CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);
setAutoFlash(captureBuilder);
// Orientation
int rotation = activity.getWindowManager().getDefaultDisplay().getRotation();
captureBuilder.set(CaptureRequest.JPEG_ORIENTATION, getOrientation(rotation));
CameraCaptureSession.CaptureCallback CaptureCallback
= new CameraCaptureSession.CaptureCallback() {
@Override
public void onCaptureCompleted(@NonNull CameraCaptureSession session,
@NonNull CaptureRequest request,
@NonNull TotalCaptureResult result) {
showToast("Saved: " + mFile);
Log.d(TAG, mFile.toString());
unlockFocus();
}
};
mCaptureSession.stopRepeating();
mCaptureSession.capture(captureBuilder.build(), CaptureCallback, null);
phototaken = !phototaken;
} catch (CameraAccessException e) {
e.printStackTrace();
}
}

问题是,我做错了什么,所以它不能在所有设备上工作?任何帮助都会很棒。

闪光灯有两个级别的控制 - 手动和由自动曝光程序控制。您目前正在将它们混合在一起。

如果要手动闪光,则需要将AE_MODE设置为AE_MODE_OFF或AE_MODE_ON,而不是任何闪光模式。 然后,FLASH_MODE将控制闪光灯是处于手电筒模式、关闭还是针对给定请求点亮一次。

由于您始终将AE_MODE置于FLASH状态之一,因此您对FLASH_MODE执行的操作无关紧要,除非某些特定设备中存在错误。

如果你想保证其他每张照片的闪光灯闪光,你需要对强制闪光照片使用AE_MODE_ON_ALWAYS_FLASH,你需要对无闪光灯使用AE_MODE_ON;不要触摸FLASH_MODE。 现在,使用AUTO_FLASH,是否触发闪光灯取决于设备,因此您会看到不同设备和照明条件下的不同行为 - 有些会触发,有些不会。

您没有做的另一件关键事情是运行预捕捉序列;这对于闪光灯照片至关重要,因为它允许设备触发预闪光以确定正确的闪光灯功率、焦点和白平衡。

若要运行预捕获,请根据需要设置AE_MODE,然后将一个请求的AE_PRECAPTURE_TRIGGER设置为 START。这将AE_STATE转换为预捕获,并且它将在那里停留一定数量的帧;一旦AE_STATE不再是预捕获,您可以发出实际的图像捕获请求。 确保在整个过程中保持AE_MODE一致。

示例应用程序Camera2Basic实现了预捕获序列,所以看看那里;它还有一些优化,如果场景不够暗,需要闪光灯,可以跳过预捕获,但由于你想强制闪光灯,这与你无关。

相关内容

  • 没有找到相关文章

最新更新