鸿蒙实战开发Camera组件:【相机】

相机组件支持相机业务的开发,开发者可以通过已开放的接口实现相机硬件的访问、操作和新功能开发,最常见的操作如:预览、拍照和录像等。

基本概念

  • 拍照

    此功能用于拍摄采集照片。

  • 预览

    此功能用于在开启相机后,在缓冲区内重复采集摄像帧,支持在拍照或录像前进行摄像帧预览显示。

  • 录像

    此功能用于在开始录像后和结束录像前的时间段内,在缓冲区内重复采集摄像帧,支持视频录制。

图 1 相机组件架构图

目录

仓目录结构如下:

/foundation/multimedia/camera_framework   # 相机组件业务代码
├── frameworks                           # 框架代码
│   ├── native                           # 内部接口实现
│   │   ├── camera                       # 相机框架实现
│   │   └── metadata                     # 元数据实现
│   └── js                               # 外部接口实现
│       └── camera_napi                  # 相机NAPI实现
├── interfaces                           # 接口代码
│   ├── inner_api                        # 内部接口
│   └── kits                             # 外部接口
├── LICENSE                              # 许可证文件
├── ohos.build                           # 构建文件
├── sa_profile                           # 服务配置文件
└── services                             # 服务代码├── camera_service                   # 相机服务实现└── etc                              # 相机服务配置

使用说明

拍照

拍照的步骤:

  1. 创建缓冲区消费者端监听器(CaptureSurfaceListener)以保存图像。

    class CaptureSurfaceListener : public IBufferConsumerListener {
    public:int32_t mode_;sptr<Surface> surface_;void OnBufferAvailable() override{int32_t flushFence = 0;int64_t timestamp = 0;OHOS::Rect damage; // initialize the damageOHOS::sptr<OHOS::SurfaceBuffer> buffer = nullptr;surface_->AcquireBuffer(buffer, flushFence, timestamp, damage);if (buffer != nullptr) {void* addr = buffer->GetVirAddr();int32_t size = buffer->GetSize();// Save the buffer(addr) to a file.surface_->ReleaseBuffer(buffer, -1);}}
    };
    
  2. 获取相机管理器实例并获取相机对象列表。

    sptr<CameraManager> camManagerObj = CameraManager::GetInstance();
    std::vector<sptr<CameraInfo>> cameraObjList = camManagerObj->GetCameras();
    
  3. 使用相机对象创建相机输入来打开相机。

    sptr<CaptureInput> cameraInput = camManagerObj->CreateCameraInput(cameraObjList[0]);
    
  4. 创建采集会话。

    sptr<CaptureSession> captureSession = camManagerObj->CreateCaptureSession();
    
  5. 开始配置采集会话。

    int32_t result = captureSession->BeginConfig();
    
  6. 将相机输入添加到采集会话。

    result = captureSession->AddInput(cameraInput);
    
  7. 创建消费者 Surface 并注册监听器以监听缓冲区更新。拍照的宽和高可以配置为所支持的 1280x960 分辨率。

    sptr<Surface> photoSurface = Surface::CreateSurfaceAsConsumer();
    int32_t photoWidth = 1280;
    int32_t photoHeight = 960;
    photoSurface->SetDefaultWidthAndHeight(photoWidth, photoHeight);
    photoSurface->SetUserData(CameraManager::surfaceFormat, std::to_string(OHOS_CAMERA_FORMAT_JPEG));
    sptr<CaptureSurfaceListener> capturelistener = new(std::nothrow) CaptureSurfaceListener();
    capturelistener->mode_ = MODE_PHOTO;
    capturelistener->surface_ = photoSurface;
    photoSurface->RegisterConsumerListener((sptr<IBufferConsumerListener> &)capturelistener);
    
  8. 使用上面创建的 Surface 创建拍照输出。

    sptr<CaptureOutput> photoOutput = camManagerObj->CreatePhotoOutput(photoSurface);
    
  9. 将拍照输出添加到采集会话。

    result = captureSession->AddOutput(photoOutput);
    
  10. 将配置提交到采集会话。

    result = captureSession->CommitConfig();
    
  11. 拍摄照片。

    result = ((sptr<PhotoOutput> &)photoOutput)->Capture();
    
  12. 释放采集会话资源。

    captureSession->Release();
    
  13. 释放相机输入关闭相机。

    cameraInput->Release();
    

开始和停止预览

开始和停止预览的步骤:

  1. 获取相机管理器实例并获取相机对象列表。

    sptr<CameraManager> camManagerObj = CameraManager::GetInstance();
    std::vector<sptr<CameraInfo>> cameraObjList = camManagerObj->GetCameras();
    
  2. 使用相机对象创建相机输入来打开相机。

    sptr<CaptureInput> cameraInput = camManagerObj->CreateCameraInput(cameraObjList[0]);
    
  3. 创建采集会话。

    sptr<CaptureSession> captureSession = camManagerObj->CreateCaptureSession();
    
  4. 开始配置采集会话。

    int32_t result = captureSession->BeginConfig();
    
  5. 将相机输入添加到采集会话。

    result = captureSession->AddInput(cameraInput);
    
  6. 使用从窗口管理器获得的 Surface 创建预览输出用以在显示上渲染。预览的宽和高可以配置为所支持的 640x480 或 832x480 分辨率,如果想保存到文件,可以按照拍照流程提到步骤,创建 Surface,注册监听器以监听缓冲区更新。

    int32_t previewWidth = 640;
    int32_t previewHeight = 480;
    previewSurface->SetUserData(CameraManager::surfaceFormat, std::to_string(OHOS_CAMERA_FORMAT_YCRCB_420_SP));
    sptr<CaptureOutput> previewOutput = camManagerObj->CreateCustomPreviewOutput(previewSurface, previewWidth, previewHeight);
    
  7. 将预览输出添加到采集会话。

    result = captureSession->AddOutput(previewOutput);
    
  8. 将配置提交到采集会话。

    result = captureSession->CommitConfig();
    
  9. 开始预览。

    result = captureSession->Start();
    
  10. 需要时停止预览。

    result = captureSession->Stop();
    
  11. 释放采集会话资源。

    captureSession->Release();
    
  12. 释放相机输入关闭相机。

    cameraInput->Release();
    

视频录像

视频录像的步骤:

  1. 获取相机管理器实例并获取相机对象列表。

    sptr<CameraManager> camManagerObj = CameraManager::GetInstance();
    std::vector<sptr<CameraInfo>> cameraObjList = camManagerObj->GetCameras();
    
  2. 使用相机对象创建相机输入来打开相机。

    sptr<CaptureInput> cameraInput = camManagerObj->CreateCameraInput(cameraObjList[0]);
    
  3. 创建采集会话。

    sptr<CaptureSession> captureSession = camManagerObj->CreateCaptureSession();
    
  4. 开始配置采集会话。

    int32_t result = captureSession->BeginConfig();
    
  5. 将相机输入添加到采集会话。

    result = captureSession->AddInput(cameraInput);
    
  6. 通过 Surface 创建一个视频输出,来与音频合成并保存到文件,Surface 通过 Recoder 获取。如果想仅保存视频缓冲数据到文件里,可以按照拍照流程提到步骤,创建 Surface,注册监听器以监听缓冲区更新。录像的分辨率可以在录制器内配置为所支持的 1280x720 或 640x360 分辨率。

    videoSurface->SetUserData(CameraManager::surfaceFormat, std::to_string(OHOS_CAMERA_FORMAT_YCRCB_420_SP));
    sptr<CaptureOutput> videoOutput = camManagerObj->CreateVideoOutput(videoSurface);
    
  7. 将视频输出添加到采集会话。

    result = captureSession->AddOutput(videoOutput);
    
  8. 将配置提交到采集会话。

    result = captureSession->CommitConfig();
    
  9. 开始视频录制。

    result = ((sptr<VideoOutput> &)videoOutput)->Start();
    
  10. 需要时停止录制。

    result = ((sptr<VideoOutput> &)videoOutput)->Stop();
    
  11. 释放采集会话的资源。

    captureSession->Release();
    
  12. 释放相机输入关闭相机。

    cameraInput->Release();
    

切换多个照相机设备

以下演示如何切换多个照相机设备。最初在采集会话中有一个视频输出(video output)。如果用户想要切换其他 照相机,现存的相机输入和输出需要先移除并加入新的相机输入和输出(示例中使用的是photo output)。

  1. 获取相机管理器实例并获取相机对象列表。

    sptr<CameraManager> camManagerObj = CameraManager::GetInstance();
    std::vector<sptr<CameraInfo>> cameraObjList = camManagerObj->GetCameras();
    
  2. 使用相机对象创建相机输入来打开相机。

    sptr<CaptureInput> cameraInput = camManagerObj->CreateCameraInput(cameraObjList[0]);
    
  3. 创建采集会话。

    sptr<CaptureSession> captureSession = camManagerObj->CreateCaptureSession();
    
  4. 开始配置采集会话。

    int32_t result = captureSession->BeginConfig()
    
  5. 将相机输入添加到采集会话。

    result = captureSession->AddInput(cameraInput);
    
  6. 通过Surface创建一个视频输出。

    sptr<CaptureOutput> videoOutput = camManagerObj->CreateVideoOutput(videoSurface);
    
  7. 将视频输出添加到采集会话。

    result = captureSession->AddOutput(videoOutput);
    
  8. 将配置提交到采集会话。

    result = captureSession->CommitConfig();
    
  9. 开始录制视频。

    result = ((sptr<VideoOutput> &)videoOutput)->Start();
    
  10. 需要时停止录制。

    result = ((sptr<VideoOutput> &)videoOutput)->Stop();
    
  11. 重新配置会话并移除相机输入和输出。

    int32_t result = captureSession->BeginConfig();
    
  12. 在新的会话配置中移除相机输入。

    int32_t result = captureSession->RemoveInput(cameraInput);
    
  13. 同样移除相机输出。

    int32_t result = captureSession->RemoveOutut(videoOutput);
    
  14. 创建新的相机输入,并把它添加到采集会话。

    sptr<CaptureInput> cameraInput2 = camManagerObj->CreateCameraInput(cameraObjList[1]);
    result = captureSession->AddInput(cameraInput2);
    
  15. 创建拍照输出,成功创建后将拍照输出添加到采集会话。创建消费者 Surface 并注册监听器以监听新的拍照输出缓冲区更新。这个 Surface 用于新创建的拍照输出。

    // Get the surface
    sptr<Surface> photoSurface = Surface::CreateSurfaceAsConsumer();
    int32_t photoWidth = 1280;
    int32_t photoHeight = 960;
    photoSurface->SetDefaultWidthAndHeight(photoWidth, photoHeight);
    photoSurface->SetUserData(CameraManager::surfaceFormat, std::to_string(OHOS_CAMERA_FORMAT_JPEG));
    sptr<CaptureSurfaceListener> capturelistener = new(std::nothrow) CaptureSurfaceListener();
    capturelistener->mode_ = MODE_PHOTO;
    capturelistener->surface_ = photoSurface;
    photoSurface->RegisterConsumerListener((sptr<IBufferConsumerListener> &)capturelistener);// Create the Photo Output
    sptr<CaptureOutput> photoOutput = camManagerObj->CreatePhotoOutput(photoSurface);// Add the output to the capture session
    result = captureSession->AddOutput(photoOutput);
    
  16. 将配置提交到采集会话。

    result = captureSession->CommitConfig();
    
  17. 释放被移出会话的相机输入。

    cameraInput->Release();
    
  18. 拍摄照片。

    result = ((sptr<PhotoOutput> &)photoOutput)->Capture();
    
  19. 释放采集会话资源。

    captureSession->Release();
    
  20. 释放相机输入关闭相机。

    cameraInput2->Release();
    

设置闪光灯

拍照和录像前可以在相机输入里设置闪光灯。

  1. 在照相中设置闪光灯。

    cameraInput->LockForControl();
    cameraInput->SetFlashMode(OHOS_CAMERA_FLASH_MODE_OPEN);
    cameraInput->UnlockForControl();
    
  2. 在录像中设置闪光灯。

    cameraInput->LockForControl();
    cameraInput->SetFlashMode(OHOS_CAMERA_FLASH_MODE_ALWAYS_OPEN);
    cameraInput->UnlockForControl();
    
  3. 关闭闪光灯。

    cameraInput->LockForControl();
    cameraInput->SetFlashMode(OHOS_CAMERA_FLASH_MODE_CLOSE);
    cameraInput->UnlockForControl();
    

    鸿蒙OpenHarmony知识已更新←前往

765e5079845b5bb77f2aa30a2da70670.jpeg

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/730629.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ARC-Challenge数据集分享

来源: AINLPer公众号&#xff08;每日干货分享&#xff01;&#xff01;&#xff09; 编辑: ShuYini 校稿: ShuYini 时间: 2024-2-28 该数据集由Allen Institute for Artificial Intelligence&#xff08;AI2&#xff09;发布&#xff0c;旨在推动高级问答的研究。该数据集包含…

3D数字孪生运行不起来?该检查你的电脑配置了

运行3D数字孪生项目通常需要一定的计算资源和图形处理能力。以下是一些常见的电脑配置要求&#xff0c;可以作为参考&#xff1a;1处理器&#xff08;CPU&#xff09;&#xff1a;推荐使用多核心处理器&#xff0c;如Intel Core i7或更高级别的处理器。较高的时钟频率和较大的缓…

kafka报文模拟工具的使用

日常项目中经常会碰到消费kafka某个topic的数据&#xff0c;如果知道报文格式&#xff0c;即可使用工具去模拟发送报文&#xff0c;以此测试代码中是否能正常消费到这个数据。 工具资源已上传&#xff0c;可直接访问连接下载&#xff1a;https://download.csdn.net/download/w…

CSS补充(下),弹性布局(上)

高级选择器 1.兄弟选择器 2.同时满足 div.bg{background-color: red;}p.bg{background-color: green;}spam.bg{background-color: blue;}注&#xff1a;选择器中间没有空格&#xff0c;有明确标识的选择器写在后面 3.各种伪类的应用 3.1作为第几个子元素 选择器:nth-child…

React-父传子

1.概念 说明&#xff1a;父组件传递数据子组件标签身上绑定属性&#xff1b;子组件接受数据props的参数。props是一个对象&#xff0c;包含父组件传递的所有数据。例如数字、字符串、布尔值、数组、对象、函数、JSX。不允许直接修改父组件传递的数据。 2.例子 // 父传子 // …

uniapp踩坑之项目:uni.previewImage简易版预览单图片

主要使用uni.previewImage //html <view class"box-card" v-for"(item,index) in DataList" :key"index"><view>图片&#xff1a;</view><image :src"item.Path" tap.stop"clickImg(item.Path)">&l…

有点NB的免费wordpress主题模板

一个不错的黄色模板&#xff0c;用WP免费主题模板搭建家政服务公司网站。 https://www.wpniu.com/themes/15.html

【性能】JDK和Jmeter的安装与配置

一、JDK环境配置 1. 下载JDK 官网下载地址&#xff1a;http://www.oracle.com/technetwork/java/javase/downloads/java-archive-downloads-javase7-521261.html 选择对应系统的安装包&#xff0c;下载后安装&#xff0c;安装中记录JDK安装的地址&#xff0c;之后一直点击下一…

继深圳后,重庆与鸿蒙展开原生应用开发合作

截至2023年底&#xff0c;开源鸿蒙开源社区已有250多家生态伙伴加入&#xff0c;开源鸿蒙项目捐赠人达35家&#xff0c;通过开源鸿蒙兼容性测评的伙伴达173个&#xff0c;累计落地230余款商用设备&#xff0c;涵盖金融、教育、智能家居、交通、数字政府、工业、医疗等各领域。 …

【Python】科研代码学习:三 PreTrainedModel, PretrainedConfig, PreTrainedTokenizer

【Python】科研代码学习&#xff1a;三 PreTrainedModel, PretrainedConfig, PreTrainedTokenizer 前言Models : PreTrainedModelPreTrainedModel 中重要的方法 tensorflow & pytorch 简单对比Configuration : PretrainedConfigPretrainedConfig 中重要的方法 Tokenizer : …

Java基础面试题(day 01)

&#x1f4d1;前言 本文主要是【Java】——Java基础面试题的文章&#xff0c;如果有什么需要改进的地方还请大佬指出⛺️ &#x1f3ac;作者简介&#xff1a;大家好&#xff0c;我是听风与他&#x1f947; ☁️博客首页&#xff1a;CSDN主页听风与他 &#x1f304;每日一句&am…

C++ 篇 数组

数组是含有多个数据项的数据结构&#xff0c;并且这些数据项都具有相同的数据类型。这些数据项称为数组的元素&#xff0c;我们可以根据元素在数组中的位置来选取元素。 最简单的数组就是一维数组。数组元素在内存中是依次排列的&#xff0c;如下图所示&#xff1a; 声明一个…

C++之创建与使用dll

目录 1、创建dll test.h test.cpp Source.def 2、使用dll testdll.cpp DLL&#xff0c;全称“Dynamic Link Library”&#xff0c;中文名为“动态链接库”&#xff0c;是一种在Windows操作系统中常见的库文件格式。它包含了可以由多个程序同时使用的代码和数据。与静态链接…

人工智能|机器学习——k-近邻算法(KNN分类算法)

1.简介 k-最近邻算法&#xff0c;也称为 kNN 或 k-NN&#xff0c;是一种非参数、有监督的学习分类器&#xff0c;它使用邻近度对单个数据点的分组进行分类或预测。虽然它可以用于回归问题&#xff0c;但它通常用作分类算法&#xff0c;假设可以在彼此附近找到相似点。 对于分类…

餐饮行业新风口:社区店的成功案例与经营秘诀

在竞争激烈的餐饮行业中&#xff0c;社区店正成为一个新的风口。作为一名90后的鲜奶吧创业者&#xff0c;我在社区开店已经5年时间&#xff0c;下面我将分享一些成功的社区店案例&#xff0c;并揭示其经营秘诀。 1、案例一&#xff1a;特色小吃店 这家小吃店以地方特色美食为…

MySQL安装与卸载

安装 1). 双击官方下来的安装包文件 2). 根据安装提示进行安装(全部默认就可以) 安装MySQL的相关组件&#xff0c;这个过程可能需要耗时几分钟&#xff0c;耐心等待。 输入MySQL中root用户的密码,一定记得记住该密码 配置 安装好MySQL之后&#xff0c;还需要配置环境变量&am…

数据结构与算法-插值查找

引言 在计算机科学的广阔天地中&#xff0c;数据结构和算法扮演着至关重要的角色。它们优化了信息处理的方式&#xff0c;使得我们在面对海量数据时能够高效、准确地进行检索与分析。本文将聚焦于一种基于有序数组且利用元素分布规律的查找算法——插值查找&#xff08;Interpo…

C++面向对象程序设计-北京大学-郭炜【课程笔记(五)】

C面向对象程序设计-北京大学-郭炜【课程笔记&#xff08;五&#xff09;】 1、常量对象、常量成员函数1.1、常量对象1.2、常量成员函数1.3、常引用 2、友元&#xff08;friends&#xff09;2.1、友元函数2.2、友元类 3、运算符重载的基本概念3.1、运算符重载 4、赋值运算符的重…

二维码门楼牌管理系统应用场景:推动旅游与文化产业的智慧化升级

文章目录 前言一、二维码门楼牌管理系统在旅游领域的应用二、二维码门楼牌管理系统在文化产业的应用三、结语 前言 随着信息技术的不断发展&#xff0c;二维码门楼牌管理系统作为一种创新的信息化手段&#xff0c;正在逐渐渗透到旅游和文化领域。它通过为文化景点、旅游景点和…

Java Map接口实现类之 HashMap

定义 public class HashMap<K,V> extends AbstractMap<K,V> implements Map<K,V>, Cloneable, Serializable{static final int DEFAULT_INITIAL_CAPACITY 1 << 4; //默认初始化容积&#xff0c;就是默认数组的长度为 16static final int MAXIMUM_CAP…