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

青春须早为,岂能长少年。这篇文章主要讲述在运行时更改Android Camera 2的Flash设置相关的知识,希望能为你提供帮助。
基本上,我想要做的是通过应用程序中的按钮单击更改CONTROL_AE_MODE。用户可以使用AUTO闪光(ON_AUTO_FLASH),如果ON(ON_ALWAYS_FLASH)或OFF(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会将整个预览变为黑色。我试着在文档中查找更新方法但没有找到任何内容。
任何教程或文档都非常感谢。
答案我不知道为什么你的预览变黑,但你不需要手动关闭捕获会话。来自.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(); }

它会快得多(几乎没有任何可见的预览冻结)。
另一答案正如@ 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)

另一答案你想要的是禁用闪光灯,而不是自动曝光(AE),因此你想使用CONTROL_AE_MODE_ON而不是CONTROL_AE_MODE_OFF
如documentation中所述:
CONTROL_AE_MODE_ON
【在运行时更改Android Camera 2的Flash设置】相机设备的自动曝光程序处于活动状态,没有闪光控制。

    推荐阅读