在 CameraX 库中创建预览后,是否每次都需要 bindToLifecycle() 来切换 ON/OFF/AUTO 闪光灯

Is bindToLifecycle() is necessary to switch ON/OFF/AUTO flash every time after creating preview in CameraX library

正如我从许多实现中了解到的,例如:

https://github.com/android/camera-samples/tree/master/CameraXBasic

https://proandroiddev.com/android-camerax-preview-analyze-capture-1b3f403a9395

在 CameraX 实现中的每个用例之后需要调用 cameraProvide.bindToLifecycle() 方法。

例如,如果我需要将相机的ON从默认的OFF模式切换到FLASH_MODE,那么再次需要调用 bindToLifecycle() 方法。

这种方法的缺点是,在一两秒钟内,预览会被删除并重新附加,这对应用程序来说并不是一个平滑的过渡。

是否有更好的做法或限制?

我在下面附上了示例代码:

   private void bindCameraUseCase() {
    int screenAspectRatio = getAspectRatio(previewView.getWidth(), previewView.getHeight());
    int rotation = previewView.getDisplay().getRotation();
    preview = new Preview.Builder()
            .setTargetAspectRatio(screenAspectRatio)
            .setTargetRotation(rotation)
            .build();
    cameraSelector = new CameraSelector.Builder()
            .requireLensFacing(lensFacing)
            .build();
    imageCapture = new ImageCapture.Builder()
            .setCaptureMode(ImageCapture.CAPTURE_MODE_MINIMIZE_LATENCY)
            .setTargetAspectRatio(screenAspectRatio)
            .setTargetRotation(rotation)
            .setFlashMode(flashMode)
            .build();
    // Must unbind the use-cases before rebinding them
    cameraProvider.unbindAll();
    preview.setSurfaceProvider(previewView.createSurfaceProvider());
    camera = cameraProvider.bindToLifecycle(this, cameraSelector, preview, imageCapture);
}

并切换手电筒:

    private void toggleFlash(){
    Log.d(TAG, "toggleFlash: "+flashMode);
    switch (flashMode){
        case ImageCapture.FLASH_MODE_OFF:
            flashMode = ImageCapture.FLASH_MODE_ON;
            flashButton.setBackgroundResource(R.drawable.ic_flash_on_24dp);
            break;
        case ImageCapture.FLASH_MODE_ON:
            flashMode = ImageCapture.FLASH_MODE_AUTO;
            break;
        case ImageCapture.FLASH_MODE_AUTO:
            flashMode = ImageCapture.FLASH_MODE_OFF;
            break;
    }
    bindCameraUseCase();
}

我使用的是 CameraX 版本 - 1.0.0-beta04

创建 ImageCapture 实例并将其绑定到生命周期后,要在图像捕获期间启用或禁用闪光灯,您可以使用 ImageCapture.setFlashMode(boolean).

关于您关于在绑定 ImageCapture 用例之前和之后设置闪光灯模式之间的区别的问题,据我所知,确实没有太大区别。当您通过调用 ImageCapture.takePicture() 拍照时,使用不同的配置参数构建一个捕获请求,其中之一是闪光模式。所以只要在这个调用之前设置flash模式(ImageCapture.takePicture()),抓包请求的输出应该是一样的

CameraX目前使用的是Camera2 under hood,为了更好地了解拍照时闪光灯模式是如何设置的,你可以看看CaptureRequest.FLASH_MODE

我看到 ImageCapture.flashMode 仅在我们使用初始配置构建期间有效,ImageCapture.Builder() 等。 但是如果你想enable/disable动态闪烁,就得用下面的

camera?.cameraControl?.enableTorch(enableFlash)

如果你想知道相机是什么?从文档中捕获它。

// A variable number of use-cases can be passed here -
// camera provides access to CameraControl & CameraInfo
camera = cameraProvider.bindToLifecycle(
this, cameraSelector, preview, imageCapture
)