首页 > 解决方案 > 如何在不建立新会话的情况下在 Camera2 API 中启用闪光灯?

问题描述

我正在开发基于 Camera2 API 的应用程序。我想在这个应用程序中添加启用/禁用闪光灯的功能。

有一些问题。我使用 3 个不同的线程进行渲染等一个,并通过处理程序在这些线程之间进行通信。当用户使用闪光灯按钮时,我想启用它,我可以这样做:

 mPreviewBuilder.set(CaptureRequest.FLASH_MODE, CaptureRequest.FLASH_MODE_SINGLE);
 mPreviewSession.setRepeatingRequest(mPreviewBuilder.build(), null, null);

但是,据我所知,创建新的预览会话是昂贵的过程,而且我也不想从相机中丢失任何帧。

有没有办法在不建立新会话的情况下启用闪光灯?或者我错了,它根本不需要很多资源?

我也想知道它是如何在标准相机应用程序中实现的。也许有任何开源代码?

提前感谢大家的回答!

标签: androidandroid-camera2

解决方案


您只需要创建一个CameraCaptureSession,然后调用它的capture()orsetRepeatingRequest()方法来发送CaptureRequests 给它,所以这根本不是一个昂贵的过程,唯一CameraCaptureSession的是在您打开CameraDevice并开始预览时创建,CameraCaptureSession会处理所有的CaptureRequests您发送并尽量不要导致任何帧丢失。

查看来自google/cameraview的代码:

void setFlash(int flash) {
    if (mFlash == flash) {
        return;
    }
    int saved = mFlash;
    mFlash = flash;
    if (mPreviewRequestBuilder != null) {
        updateFlash(); // Set the new flash settings
        if (mCaptureSession != null) {
            try {
                mCaptureSession.setRepeatingRequest(mPreviewRequestBuilder.build(),
                        mCaptureCallback, null);
            } catch (CameraAccessException e) {
                mFlash = saved; // Revert
            }
        }
    }
}

void updateFlash() {
    switch (mFlash) {
        case Constants.FLASH_OFF:
            mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AE_MODE,
                    CaptureRequest.CONTROL_AE_MODE_ON);
            mPreviewRequestBuilder.set(CaptureRequest.FLASH_MODE,
                    CaptureRequest.FLASH_MODE_OFF);
            break;
        case Constants.FLASH_ON:
            mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AE_MODE,
                    CaptureRequest.CONTROL_AE_MODE_ON_ALWAYS_FLASH);
            mPreviewRequestBuilder.set(CaptureRequest.FLASH_MODE,
                    CaptureRequest.FLASH_MODE_OFF);
            break;
        case Constants.FLASH_TORCH:
            mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AE_MODE,
                    CaptureRequest.CONTROL_AE_MODE_ON);
            mPreviewRequestBuilder.set(CaptureRequest.FLASH_MODE,
                    CaptureRequest.FLASH_MODE_TORCH);
            break;
        case Constants.FLASH_AUTO:
            mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AE_MODE,
                    CaptureRequest.CONTROL_AE_MODE_ON_AUTO_FLASH);
            mPreviewRequestBuilder.set(CaptureRequest.FLASH_MODE,
                    CaptureRequest.FLASH_MODE_OFF);
            break;
        case Constants.FLASH_RED_EYE:
            mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AE_MODE,
                    CaptureRequest.CONTROL_AE_MODE_ON_AUTO_FLASH_REDEYE);
            mPreviewRequestBuilder.set(CaptureRequest.FLASH_MODE,
                    CaptureRequest.FLASH_MODE_OFF);
            break;
    }
}

推荐阅读