当前位置: 首页 > news >正文

鸿蒙实战开发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

相关文章:

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

相机组件支持相机业务的开发&#xff0c;开发者可以通过已开放的接口实现相机硬件的访问、操作和新功能开发&#xff0c;最常见的操作如&#xff1a;预览、拍照和录像等。 基本概念 拍照 此功能用于拍摄采集照片。 预览 此功能用于在开启相机后&#xff0c;在缓冲区内重复采集…...

政安晨:【深度学习处理实践】(三)—— 处理时间序列的数据准备

在深度学习中&#xff0c;对时间序列的处理主要涉及到以下几个方面&#xff1a; 序列建模&#xff1a;深度学习可以用于对时间序列进行建模。常用的模型包括循环神经网络&#xff08;Recurrent Neural Networks, RNN&#xff09;和长短期记忆网络&#xff08;Long Short-Term M…...

PCL不同格式点云读取速度(Binary和ASCII )

首先说明一点&#xff1a;Binary(二进制)格式点云文件进行读取时要比Ascll码格式点云读取时要快的多&#xff0c;尤其是对于大型的点云文件&#xff0c;如几百万、甚至几千万个点云的情况下。 今天遇到了一种情况&#xff0c;在写项目的时候进行点云读取&#xff0c;读取的时候…...

Neo4J图数据库入门示例

前言 - Neo4j和MySQL的区别 Neo4j 和 MySQL 是两种不同类型的数据库&#xff0c;它们在数据模型、用途、性能和查询语言等方面有着显著的区别。以下是它们的主要区别&#xff1a; 数据模型&#xff1a; Neo4j 是一种图数据库&#xff0c;它使用图数据模型来存储和查询数据。在…...

牛客每日一题之 二维前缀和

题目介绍&#xff1a; 题目链接&#xff1a;【模板】二维前缀和_牛客题霸_牛客网 先举两个简单的例子&#xff0c;来帮大家理解题目&#xff0c;注意理解二维前缀和要先要一维前缀和的基础&#xff0c;不了解的可以看我上一篇博客。 若x11&#xff0c;y11, x23, y2 3,这是要…...

动态规划 Leetcode 70 爬楼梯

爬楼梯 Leetcode 70 学习记录自代码随想录 假设你正在爬楼梯。需要 n 阶你才能到达楼顶。 每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢&#xff1f; 示例 1&#xff1a; 输入&#xff1a;n 2 输出&#xff1a;2 解释&#xff1a;有两种方法可以爬到…...

(未解决)macOS matplotlib 中文是方框

reference&#xff1a; Mac OS系统下实现python matplotlib包绘图显示中文(亲测有效)_mac plt 中文值-CSDN博客 module ‘matplotlib.font_manager‘ has no attribute ‘_rebuild‘解决方法_font_manager未解析-CSDN博客 # 问题描述&#xff08;笑死 显而易见 # solve 找到…...

深入探讨C#中的递归算法

一、什么是递归算法&#xff1f; 递归是指一个函数或方法在执行过程中调用自身的情况。递归算法是编程中常见的一种解决问题的方法。它将一个问题分解成一个或多个与原问题相似但规模更小的子问题&#xff0c;然后通过解决这些子问题来解决原问题。递归算法通常用于解决重复性的…...

三款顶级开源RAG (检索增强生成)工具:Verba、Unstructured 和 Neum

三款顶级开源RAG (检索增强生成)工具&#xff1a;Verba、Unstructured 和 Neum 概述 随着企业对话式数据处理需求的提升&#xff0c;面临的挑战是数据隐私性和缺乏企业级解决方案。虽然类似LangChain能在短时间内构建RAG应用&#xff0c;但忽视了文档解析、多来源数据ETL、批量…...

VC++、MFC中操作excel时,CRange中get_EntireRow()和get_EntireColumn()函数的用法及区别是什么?

在VC和MFC中操作Excel时&#xff0c;通过COM接口与Excel交互时&#xff0c;CRange 对象&#xff08;或更准确地说是 Excel::Range 对象&#xff09;代表一个单元格范围。CRange 类提供了一系列方法来获取或操作这个范围内的单元格。其中&#xff0c;get_EntireRow() 和 get_Ent…...

npm 操作报错记录1- uninstall 卸载失效

npm 操作报错记录1- uninstall 卸载失效 1、问题描述 安装了包 vue/cli-plugin-eslint4.5.0 vue/eslint-config-prettier9.0.0 但是没有使用 -d &#xff0c;所以想重新安装&#xff0c;就使用 uninstall 命令卸载&#xff0c;结果卸载了没反应&#xff0c;也没有报错&#xf…...

openCV保存图像

保存图像 //保存为png透明通道vector<int>opts;opts.push_back(IMWRITE_PAM_FORMAT_RGB_ALPHA);imwrite("D:/img_bgra.png", img, opts);//保存为单通道灰度图像img cv::imread(imagePath.toStdString(), IMREAD_GRAYSCALE);vector<int> opts_gray;opts…...

mac 配置.bash_profile不生效问题

1、问题描述 mac系统中配置了环境变量只能在当前终端生效&#xff0c;切换了终端就无效了&#xff0c;查了下问题所在。mac系统会预装一个终极shell - zsh&#xff0c;环境变量读取在 .zshrc 文件下。 2、解决方案 1、切换终端到bash 切换终端到bash chsh -s /bin/bash 切换终端…...

【Cesium for Supermap】S3MTiles图层box裁剪

效果图&#xff1a; 代码&#xff1a; let viewer new Cesium.Viewer(cesiumContainer);// 添加SuperMap iServer发布的S3M缓存服务let promise viewer.scene.addS3MTilesLayerByScp("http://www.supermapol.com/realspace/services/3D-BIMbuilding/rest/realspace/data…...

PAT部分题目相关知识点——python

python中的整除 在Python中&#xff0c;整除&#xff08;也称为地板除&#xff09;可以使用**//**运算符来实现。当使用//运算符时&#xff0c;结果将是一个整数&#xff0c;它表示除法运算的整数部分&#xff0c;舍去任何小数部分。 示例&#xff1a; # 使用整除运算符 // …...

Redis核心数据结构之字典(二)

字典 解决键冲突 当有两个或以上数量的键被分配到了一个哈希表数组的同一个索引上面&#xff0c;我们称这些键发生了冲突(collision)。 Redis的哈希表使用链地址法(separate chaining)来解决键冲突&#xff0c;每个哈希表节点都有一个next指针&#xff0c;多个哈希表节点可以…...

拯救行动(BFS)

公主被恶人抓走&#xff0c;被关押在牢房的某个地方。牢房用 N \times M (N, M \le 200)NM(N,M≤200) 的矩阵来表示。矩阵中的每项可以代表道路&#xff08;&#xff09;、墙壁&#xff08;#&#xff09;、和守卫&#xff08;x&#xff09;。 英勇的骑士&#xff08;r&#xf…...

985硕的4家大厂实习与校招经历专题分享(part2)

我的个人经历&#xff1a; 985硕士24届毕业生&#xff0c;实验室方向:CV深度学习 就业&#xff1a;工程-java后端 关注大模型相关技术发展 校招offer: 阿里巴巴 字节跳动 等10 研究生期间独立发了一篇二区SCI 实习经历:字节 阿里 京东 B站 &#xff08;只看大厂&#xff0c;面试…...

【NR技术】 3GPP支持无人机的关键技术以及场景

1 背景 人们对使用蜂窝连接来支持无人机系统(UAS)的兴趣浓厚&#xff0c;3GPP生态系统为UAS的运行提供了极好的好处。无处不在的覆盖范围、高可靠性和QoS、强大的安全性和无缝移动性是支持UAS指挥和控制功能的关键因素。与此同时&#xff0c;监管机构正在调查安全和性能标准以及…...

【译】WordPress Bricks主题安全漏洞曝光,25,000个安装受影响

WordPress的Bricks主题存在一个严重的安全漏洞&#xff0c;恶意威胁行为者正在积极利用该漏洞在易受攻击的安装上运行任意PHP代码。 该漏洞被跟踪为CVE-2024-25600&#xff08;CVSS评分&#xff1a;9.8&#xff09;&#xff0c;使未经身份验证的攻击者能够实现远程代码执行。它…...

国防科技大学计算机基础课程笔记02信息编码

1.机内码和国标码 国标码就是我们非常熟悉的这个GB2312,但是因为都是16进制&#xff0c;因此这个了16进制的数据既可以翻译成为这个机器码&#xff0c;也可以翻译成为这个国标码&#xff0c;所以这个时候很容易会出现这个歧义的情况&#xff1b; 因此&#xff0c;我们的这个国…...

C++初阶-list的底层

目录 1.std::list实现的所有代码 2.list的简单介绍 2.1实现list的类 2.2_list_iterator的实现 2.2.1_list_iterator实现的原因和好处 2.2.2_list_iterator实现 2.3_list_node的实现 2.3.1. 避免递归的模板依赖 2.3.2. 内存布局一致性 2.3.3. 类型安全的替代方案 2.3.…...

反向工程与模型迁移:打造未来商品详情API的可持续创新体系

在电商行业蓬勃发展的当下&#xff0c;商品详情API作为连接电商平台与开发者、商家及用户的关键纽带&#xff0c;其重要性日益凸显。传统商品详情API主要聚焦于商品基本信息&#xff08;如名称、价格、库存等&#xff09;的获取与展示&#xff0c;已难以满足市场对个性化、智能…...

管理学院权限管理系统开发总结

文章目录 &#x1f393; 管理学院权限管理系统开发总结 - 现代化Web应用实践之路&#x1f4dd; 项目概述&#x1f3d7;️ 技术架构设计后端技术栈前端技术栈 &#x1f4a1; 核心功能特性1. 用户管理模块2. 权限管理系统3. 统计报表功能4. 用户体验优化 &#x1f5c4;️ 数据库设…...

return this;返回的是谁

一个审批系统的示例来演示责任链模式的实现。假设公司需要处理不同金额的采购申请&#xff0c;不同级别的经理有不同的审批权限&#xff1a; // 抽象处理者&#xff1a;审批者 abstract class Approver {protected Approver successor; // 下一个处理者// 设置下一个处理者pub…...

日常一水C

多态 言简意赅&#xff1a;就是一个对象面对同一事件时做出的不同反应 而之前的继承中说过&#xff0c;当子类和父类的函数名相同时&#xff0c;会隐藏父类的同名函数转而调用子类的同名函数&#xff0c;如果要调用父类的同名函数&#xff0c;那么就需要对父类进行引用&#…...

SpringAI实战:ChatModel智能对话全解

一、引言&#xff1a;Spring AI 与 Chat Model 的核心价值 &#x1f680; 在 Java 生态中集成大模型能力&#xff0c;Spring AI 提供了高效的解决方案 &#x1f916;。其中 Chat Model 作为核心交互组件&#xff0c;通过标准化接口简化了与大语言模型&#xff08;LLM&#xff0…...

上位机开发过程中的设计模式体会(1):工厂方法模式、单例模式和生成器模式

简介 在我的 QT/C 开发工作中&#xff0c;合理运用设计模式极大地提高了代码的可维护性和可扩展性。本文将分享我在实际项目中应用的三种创造型模式&#xff1a;工厂方法模式、单例模式和生成器模式。 1. 工厂模式 (Factory Pattern) 应用场景 在我的 QT 项目中曾经有一个需…...

前端开发者常用网站

Can I use网站&#xff1a;一个查询网页技术兼容性的网站 一个查询网页技术兼容性的网站Can I use&#xff1a;Can I use... Support tables for HTML5, CSS3, etc (查询浏览器对HTML5的支持情况) 权威网站&#xff1a;MDN JavaScript权威网站&#xff1a;JavaScript | MDN...

命令行关闭Windows防火墙

命令行关闭Windows防火墙 引言一、防火墙:被低估的"智能安检员"二、优先尝试!90%问题无需关闭防火墙方案1:程序白名单(解决软件误拦截)方案2:开放特定端口(解决网游/开发端口不通)三、命令行极速关闭方案方法一:PowerShell(推荐Win10/11)​方法二:CMD命令…...