设为首页收藏本站
网站公告 | 这是第一条公告
     

 找回密码
 立即注册
缓存时间11 现在时间11 缓存数据 我本可以容忍黑暗,如果我不曾见过太阳.然而阳光已使我荒凉,成为更新的荒凉……我啜饮过生活的芳醇,付出了什么,告诉你吧,不多不少,整整一生.

我本可以容忍黑暗,如果我不曾见过太阳.然而阳光已使我荒凉,成为更新的荒凉……我啜饮过生活的芳醇,付出了什么,告诉你吧,不多不少,整整一生. -- 现世道

查看: 597|回复: 0

Android Camera API作用及使用指南

[复制链接]

  离线 

TA的专栏

  • 打卡等级:热心大叔
  • 打卡总天数:228
  • 打卡月天数:0
  • 打卡总奖励:3481
  • 最近打卡:2025-04-13 17:26:21
等级头衔

等級:晓枫资讯-上等兵

在线时间
0 小时

积分成就
威望
0
贡献
397
主题
367
精华
0
金钱
4687
积分
822
注册时间
2023-1-4
最后登录
2025-5-31

发表于 2025-5-31 06:47:45 | 显示全部楼层 |阅读模式
一 StreamConfigurationMap


1. StreamConfigurationMap 的作用
  1. StreamConfigurationMap
复制代码
是 Android Camera2 API 中的一个核心类,用于描述相机设备支持的输出流配置,包含以下信息:

  • 支持的格式与分辨率:例如 YUV_420_888、JPEG、RAW 等格式及其对应的分辨率列表。
  • 输入/输出流组合规则:例如哪些格式可以同时用于 预览、拍照 或 录像。
  • 硬件能力限制:例如是否支持 硬件级图像处理(如 YUV 重处理)、动态范围模式(HDR)等。
  • 帧率与时长限制:如某些分辨率下支持的最小/最大帧率,或视频录制的最大时长。
应用通过
  1. CameraCharacteristics
复制代码
获取
  1. StreamConfigurationMap
复制代码
,并基于此配置合理的
  1. CaptureSession
复制代码
(例如选择预览和拍照的兼容分辨率)。

2. 与 cameraprovider 交互关系


(1) 数据来源


  • CameraProvider 提供原始数据:
Camera HAL 实现(如
  1. android.hardware.camera.provider@2.4
复制代码
)通过
  1. getCameraCharacteristics()
复制代码
方法向框架上报硬件能力,包括支持的流配置(格式、分辨率、动态范围等)。

  • 框架封装为 StreamConfigurationMap
框架层(如
  1. CameraService
复制代码
)解析 HAL 返回的元数据,将其转换为应用可直接使用的
  1. StreamConfigurationMap
复制代码


(2) 配置流程示例


  • 应用请求相机能力

    • 应用调用
      1. CameraManager.getCameraCharacteristics(cameraId)
      复制代码


  • 框架查询 HAL

      1. CameraService
      复制代码
      通过
      1. CameraProvider
      复制代码
      的 HAL 接口获取该相机的元数据。

  • HAL 返回底层配置

      1. CameraProvider
      复制代码
      从硬件或板级配置文件(如
      1. cam_board.xml
      复制代码
      )中读取支持的流配置,传递给框架。

  • 构建 StreamConfigurationMap

    • 框架将原始数据(如
      1. SCALER_AVAILABLE_STREAM_CONFIGURATIONS
      复制代码
      )封装为
      1. StreamConfigurationMap
      复制代码
      对象。

  • 应用使用配置

    • 应用根据
      1. StreamConfigurationMap
      复制代码
      选择兼容的流组合(例如同时支持
      1. 1080p@30fps
      复制代码
      预览和
      1. 12MP
      复制代码
      拍照)。


(3) 关键数据结构对应

HAL 元数据字段(如
  1. android.scaler
复制代码
)StreamConfigurationMap 方法作用
  1. SCALER_AVAILABLE_STREAM_CONFIGURATIONS
复制代码
  1. getOutputSizes(int format)
复制代码
获取某格式支持的分辨率列表
  1. SCALER_AVAILABLE_MIN_FRAME_DURATIONS
复制代码
  1. getOutputMinFrameDuration(int format)
复制代码
获取某分辨率下最小帧间隔(决定最大帧率)
  1. REQUEST_AVAILABLE_CAPABILITIES
复制代码
  1. isOutputSupportedFor(int useCase)
复制代码
检查是否支持特定用例(如 ZSL)
3. 实际示例

假设一个相机设备支持以下配置(通过
  1. CameraProvider
复制代码
上报):

  • YUV_420_888: 1920x1080@30fps, 1280x720@60fps
  • JPEG: 4000x3000@10fps
  1. StreamConfigurationMap
复制代码
会生成如下信息:
  1. // 获取 YUV 格式支持的分辨率
  2. Size[] yuvSizes = streamConfigMap.getOutputSizes(ImageFormat.YUV_420_888);
  3. // 结果: [1920x1080, 1280x720]
  4. // 检查是否支持硬件级 YUV 重处理
  5. boolean isReprocessSupported = streamConfigMap.isOutputSupportedFor(
  6.     CameraMetadata.REQUEST_AVAILABLE_CAPABILITIES_YUV_REPROCESSING);
复制代码
  1. StreamConfigurationMap
复制代码
是应用层获取相机输出能力的接口,而
  1. CameraProvider
复制代码
是底层硬件能力的提供者。前者依赖后者上报的元数据,二者共同实现 硬件能力到应用接口的透明映射,是 Android Camera 系统分层架构的核心设计之一。
在 Android 相机系统(Camera2 API)中,
  1. OutputConfiguration
复制代码
  1. StreamConfigurationMap
复制代码
是与相机输出流配置相关的两个关键类,它们在相机工作流程中扮演不同角色。以下是它们的详细介绍及关系分析:

二. OutputConfiguration


1 作用

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

  • 封装输出目标(如
    1. Surface
    复制代码
    1. SurfaceView
    复制代码
    )。
  • 配置物理相机(在多摄像头设备中指定物理传感器)。
  • 管理共享输出流(允许多个
    1. Surface
    复制代码
    共享同一输出流)。
  • 使用场景
  • 当创建
    1. CameraCaptureSession
    复制代码
    时,需传入一组
    1. OutputConfiguration
    复制代码
    对象,描述所有输出流。
  • 关键方法

      1. addSurface(Surface surface)
      复制代码
      :添加共享的
      1. Surface
      复制代码

      1. setPhysicalCameraId(String id)
      复制代码
      :指定物理相机(用于双摄/多摄设备)。
      1. getSurfaces()
      复制代码
      :获取关联的
      1. Surface
      复制代码
      列表。

  • 示例
  1. // 创建 ImageReader 并获取 Surface
  2. ImageReader imageReader = ImageReader.newInstance(width, height, format, maxImages);
  3. Surface imageSurface = imageReader.getSurface();
  4. // 创建 OutputConfiguration
  5. OutputConfiguration outputConfig = new OutputConfiguration(imageSurface);
  6. // 可选:配置共享 Surface 或物理相机
  7. // outputConfig.addSurface(anotherSurface);
  8. // outputConfig.setPhysicalCameraId("2");
  9. // 创建 CameraCaptureSession
  10. List<OutputConfiguration> outputConfigs = new ArrayList<>();
  11. outputConfigs.add(outputConfig);
  12. cameraDevice.createCaptureSessionByOutputConfigurations(outputConfigs, callback, handler);
复制代码
2. 与 StreamConfigurationMap 关系

协作流程

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

依赖关系

    1. OutputConfiguration
    复制代码
    的参数(如格式、分辨率)必须符合
    1. StreamConfigurationMap
    复制代码
    的约束,否则会话创建会失败。
    1. StreamConfigurationMap
    复制代码
    提供理论支持,
    1. OutputConfiguration
    复制代码
    负责实际配置。
扩展功能

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

3. 常见问题

Q1: 为什么需要同时使用两者?
A:
复制代码
StreamConfigurationMap
  1. 是相机设备的“能力说明书”,告诉开发者硬件支持哪些输出配置。
复制代码
OutputConfiguration
  1. 是实际构建输出流的“施工图”,将合法的参数绑定到具体的
复制代码
Surface`。
二者配合确保相机输出流的正确性和高效性

Q2: 如何避免
  1. InvalidSurfaceException
复制代码

A: 确保
  1. OutputConfiguration
复制代码
  1. Surface
复制代码
参数(格式、分辨率)在
  1. StreamConfigurationMap
复制代码
的合法范围内。

Q3: 多摄像头场景如何处理?
A: 使用
  1. OutputConfiguration.setPhysicalCameraId()
复制代码
指定物理摄像头,并通过
  1. StreamConfigurationMap
复制代码
检查该摄像头是否支持目标参数。
总结
  1. StreamConfigurationMap
复制代码
是相机设备的“能力说明书”,告诉开发者硬件支持哪些输出配置。
  1. OutputConfiguration
复制代码
是实际构建输出流的“施工图”,将合法的参数绑定到具体的
  1. Surface
复制代码
。二者配合确保相机输出流的正确性和高效性,是 Camera2 API 中不可或缺的组件。
在 Android Camera2 API 中,
  1. CameraCaptureSession
复制代码
是管理相机数据流和捕获请求的核心组件。它与
  1. OutputConfiguration
复制代码
密切相关,共同决定了相机的输出目标(如预览、拍照、录像等)的配置和运行机制。以下是详细解释及其与
  1. OutputConfiguration
复制代码
的关系:

三 CameraCaptureSession


1. 作用
  1. CameraCaptureSession
复制代码
是相机设备(
  1. CameraDevice
复制代码
)与输出目标(
  1. Surface
复制代码
)之间的桥梁,负责:
管理输出流:绑定多个
  1. Surface
复制代码
(如预览的
  1. SurfaceView
复制代码
、拍照的
  1. ImageReader
复制代码
),并确保数据正确传输到这些目标。
提交捕获请求:通过
  1. capture()
复制代码
  1. setRepeatingRequest()
复制代码
发送请求(
  1. CaptureRequest
复制代码
),控制相机的行为(如自动对焦、曝光、帧率等)。
处理异步事件:监听相机状态(如对焦完成、帧捕获完成)并回调给应用。

2 生命周期


  • 创建:通过
    1. CameraDevice.createCaptureSession()
    复制代码
    1. createCaptureSessionByOutputConfigurations()
    复制代码
    创建。
  • 活动状态:可提交捕获请求,相机数据流向绑定的
    1. Surface
    复制代码

  • 关闭:调用
    1. close()
    复制代码
    释放资源,不可再发送请求。

3.创建 CameraCaptureSession

创建会话时,需要指定一组输出目标(
  1. Surface
复制代码
  1. OutputConfiguration
复制代码
)。两种方法:
传统方式(基于
  1. Surface
复制代码
列表):
  1. cameraDevice.createCaptureSession(
  2.     List<Surface> outputs,   // 直接传递 Surface 列表
  3.     CameraCaptureSession.StateCallback callback,
  4.     Handler handler
  5. );
复制代码
适用于简单场景,但灵活性有限(例如不支持多摄像头或动态分辨率)。
基于
  1. OutputConfiguration
复制代码
的方式(API 21+,扩展功能在后续版本增强):
  1. cameraDevice.createCaptureSessionByOutputConfigurations(
  2.     List<OutputConfiguration> outputConfigurations,  // 封装了 Surface 的高级配置
  3.     CameraCaptureSession.StateCallback callback,
  4.     Handler handler
  5. );
复制代码
支持更复杂的配置(如共享流、物理摄像头绑定、动态分辨率等)。

4. 与 OutputConfiguration 的关系


(1) OutputConfiguration 是会话的输入


  • 功能:
    1. OutputConfiguration
    复制代码
    封装了一个或多个
    1. Surface
    复制代码
    的配置信息,用于定义输出流的特性:

    • 单个或共享的
      1. Surface
      复制代码
      :通过
      1. addSurface()
      复制代码
      添加多个
      1. Surface
      复制代码
      ,共享同一数据流(例如预览和录像共享同一帧数据)。
    • 物理摄像头绑定:在双摄/多摄设备中,通过
      1. setPhysicalCameraId()
      复制代码
      指定输出流来自哪个物理摄像头。
    • 动态分辨率(API 23+):允许在会话运行时动态调整分辨率(需硬件支持)。

  • 优势:相比直接传递
    1. Surface
    复制代码
    列表,
    1. OutputConfiguration
    复制代码
    提供了更细粒度的控制能力。

(2) 创建会话的流程


  • 查询设备支持:通过
    1. StreamConfigurationMap
    复制代码
    确认相机支持的格式和分辨率。
  • 创建输出目标:根据合法参数创建
    1. Surface
    复制代码
    (如
    1. ImageReader
    复制代码
    1. SurfaceView
    复制代码
    )。
  • 封装为 OutputConfiguration:将
    1. Surface
    复制代码
    及其附加配置(如物理摄像头)封装到
    1. OutputConfiguration
    复制代码

  • 创建会话:调用
    1. createCaptureSessionByOutputConfigurations()
    复制代码
    ,传入
    1. OutputConfiguration
    复制代码
    列表。

(3) 关键约束


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

5. 示例:使用 OutputConfiguration 创建会话
  1. // 创建两个输出目标:预览 Surface 和拍照 ImageReader
  2. SurfaceView surfaceView = ... // 预览的 SurfaceView
  3. ImageReader imageReader = ImageReader.newInstance(4032, 3024, ImageFormat.JPEG, 3);
  4. // 封装为 OutputConfiguration
  5. OutputConfiguration previewConfig = new OutputConfiguration(surfaceView.getHolder().getSurface());
  6. OutputConfiguration captureConfig = new OutputConfiguration(imageReader.getSurface());
  7. // 可选:配置共享流或物理摄像头
  8. // previewConfig.addSurface(anotherSurface); // 共享同一个流
  9. // captureConfig.setPhysicalCameraId("1");    // 指定物理摄像头
  10. List<OutputConfiguration> outputConfigs = new ArrayList<>();
  11. outputConfigs.add(previewConfig);
  12. outputConfigs.add(captureConfig);
  13. // 创建 CameraCaptureSession
  14. cameraDevice.createCaptureSessionByOutputConfigurations(outputConfigs,
  15.     new CameraCaptureSession.StateCallback() {
  16.         @Override
  17.         public void onConfigured(@NonNull CameraCaptureSession session) {
  18.             // 会话就绪,可提交 CaptureRequest
  19.         }
  20.         @Override
  21.         public void onConfigureFailed(@NonNull CameraCaptureSession session) {
  22.             // 配置失败(参数不合法或硬件问题)
  23.         }
  24.     },
  25.     null // 可选 Handler
  26. );
复制代码
6. 高级功能与兼容性


  • 共享流(Shared Surfaces)

    • 多个
      1. Surface
      复制代码
      共享同一输出流(例如预览和 AI 分析共享数据),减少内存和功耗。
    • 实现方式:通过
      1. OutputConfiguration.addSurface()
      复制代码
      添加多个
      1. Surface
      复制代码


  • 动态分辨率(Dynamic Resolution)(API 23+):

    • 允许在会话运行时动态调整输出分辨率(需设备支持)。
    • 通过
      1. OutputConfiguration.setDynamicRangeProfile()
      复制代码
      配置。

  • 多摄像头支持(API 28+):

    • 在双摄设备中,通过
      1. OutputConfiguration.setPhysicalCameraId()
      复制代码
      指定输出流来源。


7. 常见问题与解决方案


  • 问题1
    1. createCaptureSession
    复制代码
    失败,错误为
    1. IllegalArgumentException
    复制代码

  • 原因
    1. OutputConfiguration
    复制代码
    参数不合法(如分辨率超出支持范围)。
  • 解决:检查
    1. StreamConfigurationMap
    复制代码
    的合法参数。
  • 问题2:无法在运行时修改输出流。
  • 原因
    1. CameraCaptureSession
    复制代码
    的配置不可变。
  • 解决:关闭当前会话,重新创建新的会话。
  • 问题3:多摄像头场景下数据流混乱。
  • 原因:未正确指定
    1. setPhysicalCameraId()
    复制代码

  • 解决:确保每个
    1. OutputConfiguration
    复制代码
    绑定到正确的物理摄像头。

总结


    1. CameraCaptureSession
    复制代码
    :是相机数据流的核心控制器,负责管理输出目标和捕获请求。
    1. OutputConfiguration
    复制代码
    的关系:

      1. OutputConfiguration
      复制代码
      是会话的输入,定义了每个输出流的具体配置(如
      1. Surface
      复制代码
      、物理摄像头)。
      1. CameraCaptureSession
      复制代码
      通过
      1. OutputConfiguration
      复制代码
      的配置,确保数据流符合硬件能力(由
      1. StreamConfigurationMap
      复制代码
      定义)。
    • 使用
      1. OutputConfiguration
      复制代码
      可以启用高级功能(如共享流、多摄像头),而传统
      1. Surface
      复制代码
      列表方式功能受限。

通过合理使用
  1. OutputConfiguration
复制代码
,开发者可以更灵活地配置相机输出流,满足复杂场景的需求(如多摄、动态分辨率、低功耗共享流)。
到此这篇关于Android Camera API 介绍的文章就介绍到这了,更多相关Android Camera API内容请搜索晓枫资讯以前的文章或继续浏览下面的相关文章希望大家以后多多支持晓枫资讯!

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
晓枫资讯-科技资讯社区-免责声明
免责声明:以上内容为本网站转自其它媒体,相关信息仅为传递更多信息之目的,不代表本网观点,亦不代表本网站赞同其观点或证实其内容的真实性。
      1、注册用户在本社区发表、转载的任何作品仅代表其个人观点,不代表本社区认同其观点。
      2、管理员及版主有权在不事先通知或不经作者准许的情况下删除其在本社区所发表的文章。
      3、本社区的文章部分内容可能来源于网络,仅供大家学习与参考,如有侵权,举报反馈:点击这里给我发消息进行删除处理。
      4、本社区一切资源不代表本站立场,并不代表本站赞同其观点和对其真实性负责。
      5、以上声明内容的最终解释权归《晓枫资讯-科技资讯社区》所有。
http://bbs.yzwlo.com 晓枫资讯--游戏IT新闻资讯~~~
严禁发布广告,淫秽、色情、赌博、暴力、凶杀、恐怖、间谍及其他违反国家法律法规的内容。!晓枫资讯-社区
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|晓枫资讯--科技资讯社区 本站已运行

CopyRight © 2022-2025 晓枫资讯--科技资讯社区 ( BBS.yzwlo.com ) . All Rights Reserved .

晓枫资讯--科技资讯社区

本站内容由用户自主分享和转载自互联网,转载目的在于传递更多信息,并不代表本网赞同其观点和对其真实性负责。

如有侵权、违反国家法律政策行为,请联系我们,我们会第一时间及时清除和处理! 举报反馈邮箱:点击这里给我发消息

Powered by Discuz! X3.5

快速回复 返回顶部 返回列表