Android Camera2 SessionConfiguration介绍和使用

一、介绍

最近在相机开发中发现 createCaptureSession(List, CameraCaptureSession.StateCallback, Handler) 已经被标记为过时(@Deprecated)的函数了,取而代之的是 createCaptureSession(SessionConfiguration) 函数。

缘由

随着 Camera 功能越来越复杂,创建 Session 的方法也随之越来越多,比如:

createCaptureSession(List<Surface>, CameraCaptureSession.StateCallback, Handler)

createCaptureSessionByOutputConfigurations(List<OutputConfiguration>, CameraCaptureSession.StateCallback, Handler)

createReprocessableCaptureSession(InputConfiguration, List<Surface>, CameraCaptureSession.StateCallback, Handler)

createReprocessableCaptureSessionByConfigurations(InputConfiguration, List<OutputConfiguration>, CameraCaptureSession.StateCallback, Handler)

createConstrainedHighSpeedCaptureSession(List<Surface>, CameraCaptureSession.StateCallback, Handler)

createCustomCaptureSession(InputConfiguration, List<OutputConfiguration>, int, CameraCaptureSession.StateCallback, Handler)

于是便推出了 createCaptureSession(SessionConfiguration) 来统一。SessionConfiguration 是 Android API 28 新增的类,用于聚合捕获会话初始化的所有支持的参数。

二、常用方法

1. 构造函数

只有一个构造函数如下:

/**
 * @param sessionType 会话类型,目前有SESSION_REGULAR和SESSION_HIGH_SPEED两个值,
          后者为高速帧率范围,通常用于拍摄高速动作或慢动作视频
 * @param outputs 该会话输出的集合,不能为空
 * @param executor 用于调用回调的执行器,不建议使用主线程
 * @param cb 创建状态的回调函数,不能为空
 */
public SessionConfiguration (int sessionType, 
                List<OutputConfiguration> outputs, 
                Executor executor, 
                CameraCaptureSession.StateCallback cb)

2. 设置参数

用于设置Session创建时的使用的一些初始值。
因为这些值可以通过 CaptureRequest.Builder 在创建前就设置好然后传递给 Session 使用,可以用来根据不同的值选择相机Hal层使用的pipeline。

/**
 * @param params CaptureRequest.Builder的输出目标和不在
          CameraCharacteristics#getAvailableSessionKeys 中的参数值将会忽略,
          建议使用初始捕获请求相同的模板类型构建会话参数,以便会话和初始请求的参数尽可能匹配。
 */
public void setSessionParameters (CaptureRequest params)

3. 判断 SessionConfiguration 是否支持

这个是 CemeraDevice 类的函数,一般也会使用到。

/**
 * @param sessionConfig 目标SessionConfiguration
 */
public boolean isSessionConfigurationSupported (SessionConfiguration sessionConfig)

其余一些方法很少用,感兴趣的可以参考官网文档。

链接:https://developer.android.com/reference/android/hardware/camera2/params/SessionConfiguration

三、简单示例

一个简单的使用流程,熟悉一下创建流程。

// 创建一个 CaptureRequest.Builder 用于配置捕获请求
CaptureRequest.Builder previewRequestBuilder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
previewRequestBuilder.addTarget(surface); // surface 是用于显示预览的 Surface 对象
ArrayList<OutputConfiguration> outputConfigurations = new ArrayList<>();
for (Surface surface : allSessionOutputs) { // allSessionOutputs是所有的 Surface 集合,包含预览+拍照等
    if (surface != null) {
        OutputConfiguration configuration = new OutputConfiguration(surface);
        outputConfigurations.add(configuration);
    }
}
// 创建和设置 SessionConfiguration
CameraCaptureSession.StateCallback sessionCreateCallback = new CameraCaptureSession.StateCallback() {
    @Override
    public void onConfigured(@NonNull CameraCaptureSession session) {
        // 会话创建成功,您可以开始处理预览或拍照操作
    }
    @Override
    public void onConfigureFailed(@NonNull CameraCaptureSession session) {
        // 会话创建失败,处理错误情况
    }
};
SessionConfiguration sessionConfiguration = new SessionConfiguration(
        SessionConfiguration.SESSION_REGULAR, // SESSION_REGULAR或SESSION_HIGH_SPEED
        outputConfigurations,                 // 上面创建的ArrayList<OutputConfiguration>
        Context.getMainExecutor(),            // 回调的执行器,注意这里是不建议使用主线程的
        sessionCreateCallback);               // 回调函数
sessionConfiguration.setSessionParameters(previewRequestBuilder.build());
// 判断是否支持
try {
    boolean supported = cameraDevice.isSessionConfigurationSupported(sessionConfig);
    if (!supported) {
        // 处理不支持的情况
    }
} catch (CameraAccessException | IllegalArgumentException | NullPointerException e) {
    e.printStackTrace();
    // 处理异常的情况
}
// 创建捕捉会话
cameraDevice.createCaptureSession(sessionConfiguration);

四、自定义的回调执行器

因为不建议在主线程中执行回调,所以通常我们会创建一个相机的执行器。

1. 创建相机后台线程

这里的 mCameraHandler 同样可以用于 openCamera() 等函数使用。

private Handler mCameraHandler;
private HandlerThread mCameraThread;

// 在打开相机的时候启动线程
private void startBackgroundThread() {
    if (mCameraThread == null || mCameraHandler == null) {
        mCameraThread = new HandlerThread("CameraBackground");
        mCameraThread.start();
        mCameraHandler = new Handler(mCameraThread.getLooper());
    }
}

// 在关闭相机的时候停止线程
private void stopBackgroundThread() {
    if (mCameraThread != null) {
        mCameraThread.quitSafely();
    }
}
2. HandlerExecutor类

单独声明一个类或者内部类都可以。

public class HandlerExecutor implements Executor {
    private final Handler ihandler;

    public HandlerExecutor(Handler handler) {
        ihandler = handler;
    }

    @Override
    public void execute(Runnable runCmd) {
        ihandler.post(runCmd);
    }
}
3. 使用

只需要替换掉之前例子中的 Context.getMainExecutor() 即可。

SessionConfiguration sessionConfiguration = new SessionConfiguration(
        SessionConfiguration.SESSION_REGULAR, // SESSION_REGULAR或SESSION_HIGH_SPEED
        outputConfigurations,                 // 上面创建的ArrayList<OutputConfiguration>
        new HandlerExecutor(mCameraHandler),  // 回调的执行器,注意这里是不建议使用主线程的
        sessionCreateCallback);               // 回调函数
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
很抱歉,我之前的回答中提到的 `SessionConfiguration` 是与自然语言处理相关的,与 Android 相机开发无关。如果您要在 Android Camera2 中创建会话(Session),可以使用 `CameraCaptureSession` 类。下面是一个示例代码片段,用于创建一个 `CameraCaptureSession` 对象: ```java private CameraCaptureSession mCameraCaptureSession; private void createCameraSession() { try { Surface surface = mPreviewSurface; mImageReader = ImageReader.newInstance(mPreviewSize.getWidth(), mPreviewSize.getHeight(), ImageFormat.JPEG, 1); mImageReader.setOnImageAvailableListener(mOnImageAvailableListener, mBackgroundHandler); List<Surface> outputSurfaces = new ArrayList<>(); outputSurfaces.add(surface); outputSurfaces.add(mImageReader.getSurface()); mCameraDevice.createCaptureSession(outputSurfaces, mStateCallback, mBackgroundHandler); } catch (CameraAccessException e) { e.printStackTrace(); } } private CameraCaptureSession.StateCallback mStateCallback = new CameraCaptureSession.StateCallback() { @Override public void onConfigured(@NonNull CameraCaptureSession cameraCaptureSession) { mCameraCaptureSession = cameraCaptureSession; try { mCameraCaptureSession.setRepeatingRequest(mPreviewRequestBuilder.build(), null, mBackgroundHandler); } catch (CameraAccessException e) { e.printStackTrace(); } } @Override public void onConfigureFailed(@NonNull CameraCaptureSession cameraCaptureSession) { Log.e(TAG, "onConfigureFailed: CameraCaptureSession configuration failed"); } }; ``` 在上面的代码中,我们使用 `CameraDevice` 的 `createCaptureSession()` 方法来创建一个会话。我们在 `createCaptureSession()` 方法中指定了要输出的 `Surface` 列表,包括预览 `Surface` 和图像读取器 `Surface`。在 `onConfigured()` 方法中,我们将创建的 `CameraCaptureSession` 对象保存在变量 `mCameraCaptureSession` 中,并将预览请求设置为重复请求,这样就可以实时预览相机输出了。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值