相机组件支持相机业务的开发,开发者可以通过已开放的接口实现相机硬件的访问、操作和新功能开发,最常见的操作如:预览、拍照和录像等。
基本概念
- 拍照
此功能用于拍摄采集照片。 - 预览
此功能用于在开启相机后,在缓冲区内重复采集摄像帧,支持在拍照或录像前进行摄像帧预览显示。 - 录像
此功能用于在开始录像后和结束录像前的时间段内,在缓冲区内重复采集摄像帧,支持视频录制。
图 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 damage OHOS::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();

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。
举报投诉
-
Camera
+关注
关注
1文章
81浏览量
22035 -
鸿蒙
+关注
关注
60文章
2854浏览量
45340
发布评论请先 登录
相关推荐
热点推荐
【HarmonyOS 5】鸿蒙页面和组件生命周期函数
【HarmonyOS 5】鸿蒙页面和组件生命周期函数 ##鸿蒙开发能力 ##HarmonyOS SDK应用服务##鸿蒙金融类应用 (金融理财
鸿蒙5开发宝藏案例分享---一多开发实例(音乐)
各位开发者小伙伴们好呀!今天咱们来点硬核干货!最近在鸿蒙文档中心挖到一座“金矿”——官方竟然暗藏了100+实战案例,从分布式架构到交互动效优化应有尽有!这些案例不仅藏着华为工程师的私房技巧,还直接
鸿蒙5开发宝藏案例分享---Swiper组件性能优化实战
鸿蒙宝藏:Swiper组件性能优化实战,告别卡顿丢帧!
大家好!最近在鸿蒙开发时,偶然发现了官方文档里埋藏的 性能优化宝藏案例 ,尤其是&l
发表于 06-12 17:53
鸿蒙5开发宝藏案例分享---瀑布流优化实战分享
鸿蒙瀑布流性能优化实战:告别卡顿的宝藏指南!
大家好!最近在鸿蒙文档里挖到一个 性能优化宝藏库 ,原来官方早就准备好了各种场景的最佳实践!今天重点分享「瀑布流加载慢丢帧」的解决方案,附完整代码解析
发表于 06-12 17:41
鸿蒙5开发宝藏案例分享---性能优化案例解析
鸿蒙性能优化宝藏指南:实战工具与代码案例解析
大家好呀!今天在翻鸿蒙开发者文档时,意外挖到一个 性能优化宝藏库 ——原来官方早就提供了超多实用工具和案例,但很多小伙伴可能没发现!这篇就
发表于 06-12 16:36
鸿蒙5开发宝藏案例分享---埋点开发实战指南
鸿蒙埋点开发宝藏指南:官方案例实战解析,轻松搞定数据追踪!
大家好呀!我是HarmonyOS开发路上的探索者。最近在折腾应用埋点时,意外发现了鸿蒙
发表于 06-12 16:30
鸿蒙5开发宝藏案例分享---切面编程实战揭秘
鸿蒙切面编程(AOP)实战指南:隐藏的宝藏功能大揭秘!
大家好!今天在翻鸿蒙开发者文档时,意外发现了官方埋藏的「切面编程」宝藏案例!实际开发
发表于 06-12 16:21
鸿蒙5开发宝藏案例分享---应用架构实战技巧
大家好! 今天咱们聊聊鸿蒙开发中那些“官方文档提了但实际开发难找”的架构设计技巧。结合官方文档,我会用 真实代码案例+通俗讲解 ,帮你把分层架构和线程通信落地到项目里,告别“理论会了,代码不会
发表于 06-12 16:14
鸿蒙5开发宝藏案例分享---Pura X开发案例分享
爆发,现在吃透这些技术,你就是明年涨薪最靓的仔! **?
(原创整理不易,如果觉得有用,点个赞让我知道吧~ 下期分享\"鸿蒙分布式相机开发\"实战!)
发表于 06-12 11:47
鸿蒙5开发宝藏案例分享---折叠屏悬停态开发实践
?【鸿蒙折叠屏开发宝藏指南】原来官方藏了这么多好东西!手把手教你玩转悬停态开发**?**
Hey小伙伴们!我是你们的老朋友XX,最近在肝鸿蒙折叠屏项目时,意外挖到了官方文档里的隐藏宝藏
发表于 06-03 12:04
鸿蒙5开发宝藏案例分享---一多分栏开发实践
?【HarmonyOS开发者的宝藏指南】一次搞定多设备分栏布局,原来还能这么玩!
大家好呀!今天在鸿蒙社区挖到一个超实用的大宝藏——原来官方早就藏了一堆分栏布局的实战案例!作为被多端适配折磨
发表于 06-03 12:03
开源啦!!!基于鸿蒙ArkTS封装的图表组件《McCharts》,大家快来一起共创
的地方请大家高抬贵手,宽容一下,谢谢。
这次主要是给大家带来一个重磅消息,就是我自己使用鸿蒙ArkTS语法开发的图表组件今日正式开源了。为什么?原因有两点吧!
鸿蒙是国产的操作系统,
发表于 03-15 15:21
鸿蒙Flutter实战:14-现有Flutter 项目支持鸿蒙 II
分别安装官方的3.22版本,以及鸿蒙社区的 3.22.0 版本
3.搭建 Flutter鸿蒙开发环境
参考文章《鸿蒙Flutter实战:0
发表于 12-26 14:59

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