开发者

Android Camera API作用及使用指南

目录
  • 一 StreamConfigurationMap
    • 1. StreamConfigurationMap 的作用
    • 2. 与 cameraprovider 交互关系
      • (1) 数据来源
      • (2) 配置流程示例
      • (3) 关键数据结构对应
    • 3. 实际示例
    • 二. OutputConfiguration
      • 1 作用
        • 2. 与 StreamConfigurationMap 关系
          • 3. 常见问题
          • 三 CameraCaptureSession
            • 1. 作用
              • 2 生命周期
                • 3.创建 CameraCaptureSession
                  • 4. 与 OutputConfiguration 的关系
                    • (1) OutputConfiguration 是会话的输入
                    • (2) 创建会话的流程
                    • (3) 关键约束
                  • 5. 示例:使用 OutputConfiguration 创建会话
                    • 6. 高级功能与兼容性
                      • 7. 常见问题与解决方案
                      • 总结

                        一 StreamConfigurationMap

                        1. StreamConfigurationMap 的作用

                        StreamConfigurationMap 是 android Camera2 API 中的一个核心类,用于描述相机设备支持的输出流配置,包含以下信息:

                        • 支持的格式与分辨率:例如 YUV_420_888、JPEG、RAW 等格式及其对应的分辨率列表。
                        • 输入/输出流组合规则:例如哪些格式可以同时用于 预览、拍照 或 录像。
                        • 硬件能力限制:例如是否支持 硬件级图像处理(如 YUV 重处理)、动态范围模式(HDR)等。
                        • 帧率与时长限制:如某些分辨率下支持的最小/最大帧率,或视频录制的最大时长。

                        应用通过 CameraCharacteristics 获取 SGkqqgdpBCtreamConfigurationMap,并基于此配置合理的 CaptureSession(例如选择预览和拍照的兼容分辨率)。

                        2. 与 cameraprovider 交互关系

                        (1) 数据来源

                        • CameraProvider 提供原始数据:

                        Camera HAL 实现(如 android.编程客栈hardware.camera.provider@2.4)通过 getCameraCharacteristics() 方法向框架上报硬件能力,包括支持的流配置(格式、分辨率、动态范围等)。

                        • 框架封装为 StreamConfigurationMap

                        框架层(如 CameraService)解析 HAL 返回的元数据,将其转换为应用可直接使用的 StreamConfigurationMap

                        (2) 配置流程示例

                        • 应用请求相机能力
                          • 应用调用 CameraManager.getCameraCharacteristics(cameraId)
                        • 框架查询 HAL
                          • CameraService 通过 CameraProvider 的 HAL 接口获取该相机的元数据。
                        • HAL 返回底层配置
                          • CameraProvider 从硬件或板级配置文件(如 cam_board.XML)中读取支持的流配置,传递给框架。
                        • 构建 StreamConfigurationMap
                          • 框架将原始数据(如 SCALER_AVAILABLE_STREAM_CONFIGURATIONS)封装为 StreamConfigurationMap 对象。
                        • 应用使用配置
                          • 应用根据 StreamConfigurationMap 选择兼容的流组合(例如同时支持 1080p@30fps 预览和 12MP 拍照)。

                        (3) 关键数据结构对应

                        HAL 元数据字段(如 android.scalerStreamConfigurationMap 方法作用
                        SCALER_AVAILABLE_STREAM_CONFIGURATIONSgetOutputSizes(int format)获取某格式支持的分辨率列表
                        SCALER_AVAILABLE_MIN_FRAME_DURATIONSgetOutputMinFrameDuration(int format)获取某分辨率下最小帧间隔(决定最大帧率)
                        REQUEST_AVAILABLE_CAPABILITIESisOutputSupportedFor(int useCase)检查是否支持特定用例(如 ZSL)javascript

                        3. 实际示例

                        假设一个相机设备支持以下配置(通过 CameraProvider 上报):

                        • YUV_420_888: 1920x1080@30fps, 1280x720@60fps
                        • JPEG: 4000x3000@10fps

                        StreamConfigurationMap 会生成如下信息:

                        // 获取 YUV 格式支持的分辨率
                        Size[] yuvSizes = streamConfigMap.getOutputSizes(ImageFormat.YUV_420_8php88);
                        // 结果: [1920x1080, 1280x720]
                        // 检查是否支持硬件级 YUV 重处理
                        boolean isReprocessSupported = streamConfigMap.isOutputSupportedFor(
                            CameraMetadata.REQUEST_AVAILABLE_CAPABILITIES_YUV_REPROCESSING);

                        StreamConfigurationMap 是应用层获取相机输出能力的接口,而 CameraProvider 是底层硬件能力的提供者。前者依赖后者上报的元数据,二者共同实现 硬件能力到应用接口的透明映射,是 Android Camera 系统分层架构的核心设计之一。

                        在 Android 相机系统(Camera2 API)中,OutputConfigurationStreamConfigurationMap 是与相机输出流配置相关的两个关键类,它们在相机工作流程中扮演不同角色。以下是它们的详细介绍及关系分析:

                        二. OutputConfiguration

                        1 作用

                        作用

                        OutputConfiguration 是 Android 5.0(API 21)引入的类,用于定义单个相机输出流的配置。它的核心功能包括:

                        • 封装输出目标(如 SurfaceSurfaceView)。
                        • 配置物理相机(在多摄像头设备中指定物理传感器)。
                        • 管理共享输出流(允许多个 Surface 共享同一输出流)。
                        • 使用场景
                        • 当创建 CameraCaptureSession 时,需传入一组 OutputConfiguration 对象,描述所有输出流。
                        • 关键方法
                          • addSurface(Surface surface):添加共享的 Surface
                          • setPhysicalCameraId(String id):指定物理相机(用于双摄/多摄设备)。
                          • getSurfaces():获取关联的 Surface 列表。
                        • 示例
                        // 创建 ImageReader 并获取 Surface
                        ImageReader imageReader = ImageReader.newInstance(width, height, format, maxImages);
                        Surface imageSurface = imageReader.getSurface();
                        // 创建 OutputConfiguration
                        OutputConfiguration outputConfig = new OutputConfiguration(imageSurface);
                        // 可选:配置共享 Surface 或物理相机
                        // outputConfig.addSurface(anotherSurface);
                        // outputConfig.setPhysicalCameraId("2");
                        // 创建 CameraCaptureSession
                        List<OutputConfiguration> outputConfigs = new ArrayList<>();
                        outputConfigs.add(outputConfig);
                        cameraDevice.createCaptureSessionByOutputConfigurations(outputConfigs, callback, handler);

                        2. 与 StreamConfigurationMap 关系

                        协作流程

                        • Step 1:通过 StreamConfigurationMap 查询设备支持的输出参数(格式、分辨率等)。
                        • Step 2:根据合法参数创建输出目标(如 ImageReaderSurfaceView)。
                        • Step 3:将输出目标封装到 OutputConfiguration,用于创建 CameraCaptureSession

                        依赖关系

                        • OutputConfiguration 的参数(如格式、分辨率)必须符合 StreamConfigurationMap 的约束,否则会话创建会失败。
                        • StreamConfigurationMap 提供理论支持,OutputConfiguration 负责实际配置。

                        扩展功能

                        • OutputConfiguration 支持高级功能(如多摄像头共享输出流),而 StreamConfigurationMap 仅描述硬件能力。
                        • 在 Android 10(API 29)后,OutputConfiguration 新增对动态分辨率、物理摄像头绑定的支持。

                        3. 常见问题

                        Q1: 为什么需要同时使用两者?

                        A: StreamConfigurationMap是相机设备的“能力说明书”,告诉开发者硬件支持哪些输出配置。OutputConfiguration是实际构建输出流的“施工图”,将合法的参数绑定到具体的Surface`。

                        二者配合确保相机输出流的正确性和高效性

                        Q2: 如何避免 InvalidSurfaceException

                        A: 确保 OutputConfigurationSurface 参数(格式、分辨率)在 StreamConfigurationMap 的合法范围内。

                        Q3: 多摄像头场景如何处理?

                        A: 使用 OutputConfiguration.setPhysicalCameraId() 指定物理摄像头,并通过 StreamConfigurationMap 检查该摄像头是否支持目标参数。

                        总结 StreamConfigurationMap 是相机设备的“能力说明书”,告诉开发者硬件支持哪些输出配置。OutputConfiguration 是实际构建输出流的“施工图”,将合法的参数绑定到具体的 Surface。二者配合确保相机输出流的正确性和高效性,是 Camera2 API 中不可或缺的组件。

                        在 Android Camera2 API 中,CameraCaptureSession 是管理相机数据流和捕获请求的核心组件。它与 OutputConfiguration 密切相关,共同决定了相机的输出目标(如预览、拍照、录像等)的配置和运行机制。以下是详细解释及其与 OutputConfiguration 的关系:

                        三 CameraCaptureSession

                        1. 作用

                        CameraCaptureSession 是相机设备(CameraDevice)与输出目标(Surface)之间的桥梁,负责:

                        管理输出流:绑定多个 Surface(如预览的 SurfaceView、拍照的 ImageReader),并确保数据正确传输到这些目标。

                        提交捕获请求:通过 capture()setRepeatingRequest() 发送请求(CaptureRequest),控制相机的行为(如自动对焦、曝光、帧率等)。

                        处理异步事件:监听相机状态(如对焦完成、帧捕获完成)并回调给应用。

                        2 生命周期

                        • 创建:通过 CameraDevice.createCaptureSession()createCaptureSessionByOutputConfigurations() 创建。
                        • 活动状态:可提交捕获请求,相机数据流向绑定的 Surface
                        • 关闭:调用 close() 释放资源,不可再发送请求。

                        3.创建 CameraCaptureSession

                        创建会话时,需要指定一组输出目标(SurfaceOutputConfiguration)。两种方法:

                        传统方式(基于 Surface 列表):

                        cameraDevice.createCaptureSession(
                            List<Surface> outputs,   // 直接传递 Surface 列表
                            CameraCaptureSession.StateCallback callback, 
                            Handler handler
                        );

                        适用于简单场景,但灵活性有限(例如不支持多摄像头或动态分辨率)。

                        基于 OutputConfiguration 的方式(API 21+,扩展功能在后续版本增强):

                        cameraDevice.createCaptureSessionByOutputConfigurations(
                            List<OutputConfiguration> outputConfigurations,  // 封装了 Surface 的高级配置
                            CameraCaptureSession.StateCallback callback,
                            Handler handler
                        );

                        支持更复杂的配置(如共享流、物理摄像头绑定、动态分辨率等)。

                        4. 与 OutputConfiguration 的关系

                        (1) OutputConfiguration 是会话的输入

                        • 功能:OutputConfiguration 封装了一个或多个 Surface 的配置信息,用于定义输出流的特性:
                          • 单个或共享的 Surface:通过 addSurface() 添加多个 Surface,共享同一数据流(例如预览和录像共享同一帧数据)。
                          • 物理摄像头绑定:在双摄/多摄设备中,通过 setPhysicalCameraId() 指定输出流来自哪个物理摄像头。
                          • 动态分辨率(API 23+):允许在会话运行时动态调整分辨率(需硬件支持)。
                        • 优势:相比直接传递 Surface 列表,OutputConfiguration 提供了更细粒度的控制能力。

                        (2) 创建会话的流程

                        • 查询设备支持:通过 StreamConfigurationMap 确认相机支持的格式和分辨率。
                        • 创建输出目标:根据合法参数创建 Surface(如 ImageReaderSurfaceView)。
                        • 封装为 OutputConfiguration:将 Surface 及其附加配置(如物理摄像头)封装到 OutputConfiguration
                        • 创建会话:调用 createCaptureSessionByOutputConfigurations(),传入 OutputConfiguration 列表。

                        (3) 关键约束

                        • 不可变性:一旦 CameraCaptureSession 创建成功,其绑定的 OutputConfiguration 不可修改(如新增或移除 Surface)。若需更改,必须关闭当前会话并重新创建。
                        • 硬件限制OutputConfiguration 的配置(如分辨率、格式)必须符合 StreamConfigurationMap 的支持范围。

                        5. 示例:使用 OutputConfiguration 创建会话

                        // 创建两个输出目标:预览 Surface 和拍照 ImageReader
                        SurfaceView surfaceView = ... // 预览的 SurfaceView
                        ImageReader imageReader = ImageReader.newInstance(4032, 3024, ImageFormat.JPEG, 3);
                        // 封装为 OutputConfiguration
                        OutputConfiguration previewConfig = new OutputConfiguration(surfaceView.getHolder().getSurface());
                        OutputConfiguration captureConfig = new OutputConfiguration(imageReader.getSurface());
                        // 可选:配置共享流或物理摄像头
                        // previewConfig.addSurface(anotherSurface); // 共享同一个流
                        // captureConfig.setPhysicalCameraId("1");    // 指定物理摄像头
                        List<OutputConfiguration> outputConfigs = new ArrayList<>();
                        outputConfigs.add(previewConfig);
                        outputConfigs.add(captureConfig);
                        // 创建 CameraCaptureSession
                        cameraDevice.createCaptureSessionByOutputConfigurations(outputConfigs, 
                            new CameraCaptureSession.StateCallback() {
                                @Override
                                public void onConfigured(@NonNull CameraCaptureSession session) {
                                    // 会话就绪,可提交 CaptureRequest
                                }
                                @Override
                                public void onConfigureFailed(@NonNull CameraCaptureSession session) {
                                    // 配置失败(参数不合法或硬件问题)
                                }
                            }, 
                            null // 可选 Handler
                        );

                        6. 高级功能与兼容性

                        • 共享流(Shared Surfaces)
                          • 多个 Surface 共享同一输出流(例如预览和 AI 分析共享数据),减少内存和功耗。
                          • 实现方式:通过 OutputConfiguration.addSurface() 添加多个 Surface
                        • 动态分辨率(Dynamic Resolution)(API 23+):
                          • 允许在会话运行时动态调整输出分辨率(需设备支持)。
                          • 通过 OutputConfiguration.setDynamicRangeProfile() 配置。
                        • 多摄像头支持(API 28+):
                          • 在双摄设备中,js通过 OutputConfiguration.setPhysicalCameraId() 指定输出流来源。

                        7. 常见问题与解决方案

                        • 问题1createCaptureSession 失败,错误为 IllegalArgumentException
                        • 原因OutputConfiguration 参数不合法(如分辨率超出支持范围)。
                        • 解决:检查 StreamConfigurationMap 的合法参数。
                        • 问题2:无法在运行时修改输出流。
                        • 原因CameraCaptureSession 的配置不可变。
                        • 解决:关闭当前会话,重新创建新的会话。
                        • 问题3:多摄像头场景下数据流混乱。
                        • 原因:未正确指定 setPhysicalCameraId()
                        • 解决:确保每个 OutputConfiguration 绑定到正确的物理摄像头。

                        总结

                        • CameraCaptureSession:是相机数据流的核心控制器,负责管理输出目标和捕获请求。
                        • OutputConfiguration 的关系:
                          • OutputConfiguration 是会话的输入,定义了每个输出流的具体配置(如 Surface、物理摄像头)。
                          • CameraCaptureSession 通过 OutputConfiguration 的配置,确保数据流符合硬件能力(由 StreamConfigurationMap 定义)。
                          • 使用 OutputConfiguration 可以启用高级功能(如共享流、多摄像头),而传统 Surface 列表方式功能受限。

                        通过合理使用 OutputConfiguration,开发者可以更灵活地配置相机输出流,满足复杂场景的需求(如多摄、动态分辨率、低功耗共享流)。

                        到此这篇关于Android Camera API 介绍的文章就介绍到这了,更多相关Android Camera API内容请搜索编程客栈(www.devze.com)以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程客栈(www.devze.com)!

                        0

                        上一篇:

                        下一篇:

                        精彩评论

                        暂无评论...
                        验证码 换一张
                        取 消

                        最新开发

                        开发排行榜