在运行时更改Android Camera 2的Flash设置

7
基本上,我想通过应用程序中的按钮点击来更改CONTROL_AE_MODE。用户可以使用自动闪光灯(ON_AUTO_FLASH),将其打开(ON_ALWAYS_FLASH)或关闭(CONTROL_AE_MODE_OFF)。
在这个例子中:https://github.com/googlesamples/android-Camera2Basic/blob/master/Application/src/main/java/com/example/android/camera2basic/Camera2BasicFragment.java 他们在第818行设置一次闪光灯:
// 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, ORIENTATIONS.get(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);

然后在第840行构建了CaptureSession。

预览之后是否有办法更改CONTROL_AE_MODE?

我尝试重新制作会话,有点起作用:

if(flashMode == CameraView.CAMERA_FLASH_ON){
            Log.e("CAMERA 2", "FLASH ON");
            mPreviewCaptureRequestBuilder.set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_ON_ALWAYS_FLASH);
        }else if(flashMode == CameraView.CAMERA_FLASH_OFF){
            Log.e("CAMERA 2", "FLASH OFF");
            mPreviewCaptureRequestBuilder.set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_OFF);
        }else if(flashMode == CameraView.CAMERA_FLASH_AUTO){
            Log.e("CAMERA 2", "FLASH AUTO");
            mPreviewCaptureRequestBuilder.set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_ON_AUTO_FLASH);
        }
        mFlashMode = flashMode;
        if (mCameraCaptureSession != null) {
            mCameraCaptureSession.close();
            mCameraCaptureSession = null;
       }
  createCameraPreviewSession();

因为某些原因,CONTROL_AE_MODE_OFF 会使整个预览变黑。

我尝试查找更新方法的文档,但没有找到任何信息。

非常感谢任何教程或文档。


你解决了这个问题吗?CONTROL_AE_MODE_OFF 对我也是黑屏。 - emen
你可能有一个例子吗?或者可以告诉我应该在哪个方法中包含这几行代码?是在stillCapture()onConfigurate()还是unlockFocus()方法中?因为我找不到任何能使我的代码工作的东西... - Sirop4ik
3个回答

7

正如@cyborg86pl所提到的,当切换闪光模式时,不应该切换CONTROL_AE_MODE。相反,你可以在FLASH_MODE之间切换。这是我个人案例的一个可行示例:

  when (currentFlashState) {
        FlashState.AUTO -> {
          previewRequestBuilder.set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_ON_AUTO_FLASH)
        }
        FlashState.ON -> {
          previewRequestBuilder.set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_ON)
          previewRequestBuilder.set(CaptureRequest.FLASH_MODE, CameraMetadata.FLASH_MODE_TORCH)
        }
        FlashState.OFF -> {
          previewRequestBuilder.set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_ON)
          previewRequestBuilder.set(CaptureRequest.FLASH_MODE, CaptureRequest.FLASH_MODE_OFF)
        }
      }
 previewRequest = previewRequestBuilder.build()
 captureSession.setRepeatingRequest(previewRequest, captureCallback, backgroundHandler)

4
我不知道为什么你的预览会变成黑色,但是你不需要手动关闭捕获会话。从 .close() 方法的文档中可以看到:使用 createCaptureSession(List , CameraCaptureSession.StateCallback, Handler) 直接切换到新会话而不关闭旧会话,这是推荐的方法,因为未更改的目标输出可以更有效地重复使用。因此,您可以重用现有的 CaptureRequest.Builder,设置您更改的值,构建新的 PreviewRequest,然后使用这个新请求开始新的会话,如下所示:
try {
    // Change some capture settings
    mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_ON);
    // Build new request (we can't just edit existing one, as it is immutable)
    mPreviewRequest = mPreviewRequestBuilder.build();
    // Set new repeating request with our changed one
    mCaptureSession.setRepeatingRequest(mPreviewRequest, mCaptureCallback, mBackgroundHandler);
} catch (CameraAccessException e) {
    e.printStackTrace();
}

它会更快(几乎没有任何可见的预览冻结)。

也许你有示例代码吗?或者告诉我应该在哪个方法中包含这些代码?是在 stillCapture()onConfigurate() 还是 unlockFocus() 方法中?因为我找不到任何可以使我的代码工作的东西... - Sirop4ik

1
你想要的是禁用闪光灯,而不是自动曝光(AE),因此你需要使用 CONTROL_AE_MODE_ON 而不是 CONTROL_AE_MODE_OFF
文档 中所述:

CONTROL_AE_MODE_ON

相机设备的自动曝光程序处于活动状态,但无闪光灯控制。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接