鸿蒙实战开发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 # 相机服务配置
使用说明
拍照
拍照的步骤:
-
创建缓冲区消费者端监听器(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);}} }; -
获取相机管理器实例并获取相机对象列表。
sptr<CameraManager> camManagerObj = CameraManager::GetInstance(); std::vector<sptr<CameraInfo>> cameraObjList = camManagerObj->GetCameras(); -
使用相机对象创建相机输入来打开相机。
sptr<CaptureInput> cameraInput = camManagerObj->CreateCameraInput(cameraObjList[0]); -
创建采集会话。
sptr<CaptureSession> captureSession = camManagerObj->CreateCaptureSession(); -
开始配置采集会话。
int32_t result = captureSession->BeginConfig(); -
将相机输入添加到采集会话。
result = captureSession->AddInput(cameraInput); -
创建消费者 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); -
使用上面创建的 Surface 创建拍照输出。
sptr<CaptureOutput> photoOutput = camManagerObj->CreatePhotoOutput(photoSurface); -
将拍照输出添加到采集会话。
result = captureSession->AddOutput(photoOutput); -
将配置提交到采集会话。
result = captureSession->CommitConfig(); -
拍摄照片。
result = ((sptr<PhotoOutput> &)photoOutput)->Capture(); -
释放采集会话资源。
captureSession->Release(); -
释放相机输入关闭相机。
cameraInput->Release();
开始和停止预览
开始和停止预览的步骤:
-
获取相机管理器实例并获取相机对象列表。
sptr<CameraManager> camManagerObj = CameraManager::GetInstance(); std::vector<sptr<CameraInfo>> cameraObjList = camManagerObj->GetCameras(); -
使用相机对象创建相机输入来打开相机。
sptr<CaptureInput> cameraInput = camManagerObj->CreateCameraInput(cameraObjList[0]); -
创建采集会话。
sptr<CaptureSession> captureSession = camManagerObj->CreateCaptureSession(); -
开始配置采集会话。
int32_t result = captureSession->BeginConfig(); -
将相机输入添加到采集会话。
result = captureSession->AddInput(cameraInput); -
使用从窗口管理器获得的 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); -
将预览输出添加到采集会话。
result = captureSession->AddOutput(previewOutput); -
将配置提交到采集会话。
result = captureSession->CommitConfig(); -
开始预览。
result = captureSession->Start(); -
需要时停止预览。
result = captureSession->Stop(); -
释放采集会话资源。
captureSession->Release(); -
释放相机输入关闭相机。
cameraInput->Release();
视频录像
视频录像的步骤:
-
获取相机管理器实例并获取相机对象列表。
sptr<CameraManager> camManagerObj = CameraManager::GetInstance(); std::vector<sptr<CameraInfo>> cameraObjList = camManagerObj->GetCameras(); -
使用相机对象创建相机输入来打开相机。
sptr<CaptureInput> cameraInput = camManagerObj->CreateCameraInput(cameraObjList[0]); -
创建采集会话。
sptr<CaptureSession> captureSession = camManagerObj->CreateCaptureSession(); -
开始配置采集会话。
int32_t result = captureSession->BeginConfig(); -
将相机输入添加到采集会话。
result = captureSession->AddInput(cameraInput); -
通过 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); -
将视频输出添加到采集会话。
result = captureSession->AddOutput(videoOutput); -
将配置提交到采集会话。
result = captureSession->CommitConfig(); -
开始视频录制。
result = ((sptr<VideoOutput> &)videoOutput)->Start(); -
需要时停止录制。
result = ((sptr<VideoOutput> &)videoOutput)->Stop(); -
释放采集会话的资源。
captureSession->Release(); -
释放相机输入关闭相机。
cameraInput->Release();
切换多个照相机设备
以下演示如何切换多个照相机设备。最初在采集会话中有一个视频输出(video output)。如果用户想要切换其他 照相机,现存的相机输入和输出需要先移除并加入新的相机输入和输出(示例中使用的是photo output)。
-
获取相机管理器实例并获取相机对象列表。
sptr<CameraManager> camManagerObj = CameraManager::GetInstance(); std::vector<sptr<CameraInfo>> cameraObjList = camManagerObj->GetCameras(); -
使用相机对象创建相机输入来打开相机。
sptr<CaptureInput> cameraInput = camManagerObj->CreateCameraInput(cameraObjList[0]); -
创建采集会话。
sptr<CaptureSession> captureSession = camManagerObj->CreateCaptureSession(); -
开始配置采集会话。
int32_t result = captureSession->BeginConfig() -
将相机输入添加到采集会话。
result = captureSession->AddInput(cameraInput); -
通过Surface创建一个视频输出。
sptr<CaptureOutput> videoOutput = camManagerObj->CreateVideoOutput(videoSurface); -
将视频输出添加到采集会话。
result = captureSession->AddOutput(videoOutput); -
将配置提交到采集会话。
result = captureSession->CommitConfig(); -
开始录制视频。
result = ((sptr<VideoOutput> &)videoOutput)->Start(); -
需要时停止录制。
result = ((sptr<VideoOutput> &)videoOutput)->Stop(); -
重新配置会话并移除相机输入和输出。
int32_t result = captureSession->BeginConfig(); -
在新的会话配置中移除相机输入。
int32_t result = captureSession->RemoveInput(cameraInput); -
同样移除相机输出。
int32_t result = captureSession->RemoveOutut(videoOutput); -
创建新的相机输入,并把它添加到采集会话。
sptr<CaptureInput> cameraInput2 = camManagerObj->CreateCameraInput(cameraObjList[1]); result = captureSession->AddInput(cameraInput2); -
创建拍照输出,成功创建后将拍照输出添加到采集会话。创建消费者 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); -
将配置提交到采集会话。
result = captureSession->CommitConfig(); -
释放被移出会话的相机输入。
cameraInput->Release(); -
拍摄照片。
result = ((sptr<PhotoOutput> &)photoOutput)->Capture(); -
释放采集会话资源。
captureSession->Release(); -
释放相机输入关闭相机。
cameraInput2->Release();
设置闪光灯
拍照和录像前可以在相机输入里设置闪光灯。
-
在照相中设置闪光灯。
cameraInput->LockForControl(); cameraInput->SetFlashMode(OHOS_CAMERA_FLASH_MODE_OPEN); cameraInput->UnlockForControl(); -
在录像中设置闪光灯。
cameraInput->LockForControl(); cameraInput->SetFlashMode(OHOS_CAMERA_FLASH_MODE_ALWAYS_OPEN); cameraInput->UnlockForControl(); -
关闭闪光灯。
cameraInput->LockForControl(); cameraInput->SetFlashMode(OHOS_CAMERA_FLASH_MODE_CLOSE); cameraInput->UnlockForControl();鸿蒙OpenHarmony知识已更新←前往

相关文章:
鸿蒙实战开发Camera组件:【相机】
相机组件支持相机业务的开发,开发者可以通过已开放的接口实现相机硬件的访问、操作和新功能开发,最常见的操作如:预览、拍照和录像等。 基本概念 拍照 此功能用于拍摄采集照片。 预览 此功能用于在开启相机后,在缓冲区内重复采集…...
政安晨:【深度学习处理实践】(三)—— 处理时间序列的数据准备
在深度学习中,对时间序列的处理主要涉及到以下几个方面: 序列建模:深度学习可以用于对时间序列进行建模。常用的模型包括循环神经网络(Recurrent Neural Networks, RNN)和长短期记忆网络(Long Short-Term M…...
PCL不同格式点云读取速度(Binary和ASCII )
首先说明一点:Binary(二进制)格式点云文件进行读取时要比Ascll码格式点云读取时要快的多,尤其是对于大型的点云文件,如几百万、甚至几千万个点云的情况下。 今天遇到了一种情况,在写项目的时候进行点云读取,读取的时候…...
Neo4J图数据库入门示例
前言 - Neo4j和MySQL的区别 Neo4j 和 MySQL 是两种不同类型的数据库,它们在数据模型、用途、性能和查询语言等方面有着显著的区别。以下是它们的主要区别: 数据模型: Neo4j 是一种图数据库,它使用图数据模型来存储和查询数据。在…...
牛客每日一题之 二维前缀和
题目介绍: 题目链接:【模板】二维前缀和_牛客题霸_牛客网 先举两个简单的例子,来帮大家理解题目,注意理解二维前缀和要先要一维前缀和的基础,不了解的可以看我上一篇博客。 若x11,y11, x23, y2 3,这是要…...
动态规划 Leetcode 70 爬楼梯
爬楼梯 Leetcode 70 学习记录自代码随想录 假设你正在爬楼梯。需要 n 阶你才能到达楼顶。 每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢? 示例 1: 输入:n 2 输出:2 解释:有两种方法可以爬到…...
(未解决)macOS matplotlib 中文是方框
reference: Mac OS系统下实现python matplotlib包绘图显示中文(亲测有效)_mac plt 中文值-CSDN博客 module ‘matplotlib.font_manager‘ has no attribute ‘_rebuild‘解决方法_font_manager未解析-CSDN博客 # 问题描述(笑死 显而易见 # solve 找到…...
深入探讨C#中的递归算法
一、什么是递归算法? 递归是指一个函数或方法在执行过程中调用自身的情况。递归算法是编程中常见的一种解决问题的方法。它将一个问题分解成一个或多个与原问题相似但规模更小的子问题,然后通过解决这些子问题来解决原问题。递归算法通常用于解决重复性的…...
三款顶级开源RAG (检索增强生成)工具:Verba、Unstructured 和 Neum
三款顶级开源RAG (检索增强生成)工具:Verba、Unstructured 和 Neum 概述 随着企业对话式数据处理需求的提升,面临的挑战是数据隐私性和缺乏企业级解决方案。虽然类似LangChain能在短时间内构建RAG应用,但忽视了文档解析、多来源数据ETL、批量…...
VC++、MFC中操作excel时,CRange中get_EntireRow()和get_EntireColumn()函数的用法及区别是什么?
在VC和MFC中操作Excel时,通过COM接口与Excel交互时,CRange 对象(或更准确地说是 Excel::Range 对象)代表一个单元格范围。CRange 类提供了一系列方法来获取或操作这个范围内的单元格。其中,get_EntireRow() 和 get_Ent…...
npm 操作报错记录1- uninstall 卸载失效
npm 操作报错记录1- uninstall 卸载失效 1、问题描述 安装了包 vue/cli-plugin-eslint4.5.0 vue/eslint-config-prettier9.0.0 但是没有使用 -d ,所以想重新安装,就使用 uninstall 命令卸载,结果卸载了没反应,也没有报错…...
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系统中配置了环境变量只能在当前终端生效,切换了终端就无效了,查了下问题所在。mac系统会预装一个终极shell - zsh,环境变量读取在 .zshrc 文件下。 2、解决方案 1、切换终端到bash 切换终端到bash chsh -s /bin/bash 切换终端…...
【Cesium for Supermap】S3MTiles图层box裁剪
效果图: 代码: 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中,整除(也称为地板除)可以使用**//**运算符来实现。当使用//运算符时,结果将是一个整数,它表示除法运算的整数部分,舍去任何小数部分。 示例: # 使用整除运算符 // …...
Redis核心数据结构之字典(二)
字典 解决键冲突 当有两个或以上数量的键被分配到了一个哈希表数组的同一个索引上面,我们称这些键发生了冲突(collision)。 Redis的哈希表使用链地址法(separate chaining)来解决键冲突,每个哈希表节点都有一个next指针,多个哈希表节点可以…...
拯救行动(BFS)
公主被恶人抓走,被关押在牢房的某个地方。牢房用 N \times M (N, M \le 200)NM(N,M≤200) 的矩阵来表示。矩阵中的每项可以代表道路()、墙壁(#)、和守卫(x)。 英勇的骑士(r…...
985硕的4家大厂实习与校招经历专题分享(part2)
我的个人经历: 985硕士24届毕业生,实验室方向:CV深度学习 就业:工程-java后端 关注大模型相关技术发展 校招offer: 阿里巴巴 字节跳动 等10 研究生期间独立发了一篇二区SCI 实习经历:字节 阿里 京东 B站 (只看大厂,面试…...
【NR技术】 3GPP支持无人机的关键技术以及场景
1 背景 人们对使用蜂窝连接来支持无人机系统(UAS)的兴趣浓厚,3GPP生态系统为UAS的运行提供了极好的好处。无处不在的覆盖范围、高可靠性和QoS、强大的安全性和无缝移动性是支持UAS指挥和控制功能的关键因素。与此同时,监管机构正在调查安全和性能标准以及…...
【译】WordPress Bricks主题安全漏洞曝光,25,000个安装受影响
WordPress的Bricks主题存在一个严重的安全漏洞,恶意威胁行为者正在积极利用该漏洞在易受攻击的安装上运行任意PHP代码。 该漏洞被跟踪为CVE-2024-25600(CVSS评分:9.8),使未经身份验证的攻击者能够实现远程代码执行。它…...
Phi-3.5-mini-instruct免配置优势:系统重启后自动恢复,无须人工干预
Phi-3.5-mini-instruct免配置优势:系统重启后自动恢复,无须人工干预 1. 开箱即用的轻量级文本助手 Phi-3.5-mini-instruct是一款专为中文场景优化的轻量级文本生成模型,它已经完成了网页封装,用户无需任何技术背景即可直接使用。…...
为什么你的QQ空间记忆需要GetQzonehistory来永久保存?
为什么你的QQ空间记忆需要GetQzonehistory来永久保存? 【免费下载链接】GetQzonehistory 获取QQ空间发布的历史说说 项目地址: https://gitcode.com/GitHub_Trending/ge/GetQzonehistory 在数字时代,我们的记忆正以惊人的速度消失。你是否曾试图找…...
Unity Shader 深度重建世界坐标
只用一张深度图就能还原每个像素对应的世界空间位置:用 NDC 坐标 逆 VP 矩阵反算。这是 SSAO、SSR、体积雾等所有屏幕空间效果的底层基础。一、核心原理当我们渲染一个 3D 场景时,GPU 会将顶点从世界空间变换到屏幕空间,这个过程涉及 View 矩…...
STT错误排查手册:10个常见问题解决方案与性能调优终极指南
STT错误排查手册:10个常见问题解决方案与性能调优终极指南 【免费下载链接】stt Voice Recognition to Text Tool / 一个离线运行的本地音视频转字幕工具,输出json、srt字幕、纯文字格式 项目地址: https://gitcode.com/gh_mirrors/stt/stt STT&a…...
注意力机制模块:老树发新芽:SE 注意力结合硬件友好型 Swish 激活函数,在边缘端模型中的极限优化
前言:边缘AI的「不可能三角」与两条救赎路径 2026年的边缘AI领域正在经历一场静默的革命。Google的TPU v7 Ironwood芯片、Qualcomm的77 TOPS物联网处理器、Ambiq基于Arm Ethos-U85的Atomiq SoC——这些硅基巨兽的算力一路飙升,但当我们把目光从云端数据中心转向智能家居、工…...
靠谱的霍比特小屋供应商
靠谱的霍比特小屋供应商——山东溶石洞穴景观装饰工程在当今追求独特与个性化的时代,霍比特小屋凭借其童话般的外观和温馨的氛围,成为众多人心中理想的居住或休闲空间。而在寻找靠谱的霍比特小屋供应商时,山东溶石洞穴景观装饰工程脱颖而出&a…...
收藏!国网四川电力 2026 年度集中采购批次计划发布
国网四川省电力公司公示的《2026 年度集中采购批次计划》,明确全年 108 个采购批次,为供应商精准把握投标节奏、提前布局业务提供清晰指引。本次采购覆盖 2025 年 12 月至 2026 年 11 月,涵盖省公司本级、子公司、战新产业及原集体企业等全主…...
像素史诗·智识终端Java开发环境快速配置:基于镜像的一站式解决方案
像素史诗智识终端Java开发环境快速配置:基于镜像的一站式解决方案 1. 为什么选择镜像部署Java开发环境 对于Java开发者来说,环境配置一直是个头疼的问题。不同版本的JDK、Maven仓库配置、IDE插件安装...这些繁琐的准备工作往往要耗费半天甚至更长时间。…...
ICL8038信号发生器DIY全攻略:从原理图到波形调试(附AD源文件)
ICL8038信号发生器DIY全攻略:从原理图到波形调试 在电子工程领域,信号发生器是实验室和研发工作中不可或缺的基础设备。市面上的专业信号发生器往往价格昂贵,而基于ICL8038芯片的DIY方案,能以极低成本实现实验室级别的多功能波形输…...
鱼音频生成 API 集成指南
在这篇文章中,我们将介绍如何集成鱼音频生成 API,该 API 能够通过输入提示词来克隆您的声音。这项技术的应用场景包括语音合成、自动化语音助手、以及任何需要个性化语音输出的应用。 环境准备 在使用鱼音频生成 API 之前,您需要先申请相应…...
