0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

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

jf_46214456 来源:jf_46214456 作者:jf_46214456 2024-03-08 16:20 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

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

基本概念

  • 拍照
    此功能用于拍摄采集照片。
  • 预览
    此功能用于在开启相机后,在缓冲区内重复采集摄像帧,支持在拍照或录像前进行摄像帧预览显示。
  • 录像
    此功能用于在开始录像后和结束录像前的时间段内,在缓冲区内重复采集摄像帧,支持视频录制。

图 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 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);
            }
        }
    };
    
  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();
  1. 拍摄照片。
result = ((sptr<  PhotoOutput > &)photoOutput)- >Capture();
  1. 释放采集会话资源。
captureSession- >Release();
  1. 释放相机输入关闭相机。
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();
  1. 释放采集会话资源。
captureSession- >Release();
  1. 释放相机输入关闭相机。
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();
  1. 释放采集会话的资源。
captureSession- >Release();
  1. 释放相机输入关闭相机。
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();
  1. 重新配置会话并移除相机输入和输出。
int32_t result = captureSession- >BeginConfig();
  1. 在新的会话配置中移除相机输入。
int32_t result = captureSession- >RemoveInput(cameraInput);
  1. 同样移除相机输出。
int32_t result = captureSession- >RemoveOutut(videoOutput);
  1. 创建新的相机输入,并把它添加到采集会话。
sptr< CaptureInput > cameraInput2 = camManagerObj- >CreateCameraInput(cameraObjList[1]);
result = captureSession- >AddInput(cameraInput2);
  1. 创建拍照输出,成功创建后将拍照输出添加到采集会话。创建消费者 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);
  1. 将配置提交到采集会话。
result = captureSession- >CommitConfig();
  1. 释放被移出会话的相机输入。
cameraInput- >Release();
  1. 拍摄照片。
result = ((sptr<  PhotoOutput > &)photoOutput)- >Capture();
  1. 释放采集会话资源。
captureSession- >Release();
  1. 释放相机输入关闭相机。
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
    +关注

    关注

    1

    文章

    81

    浏览量

    22035
  • 鸿蒙
    +关注

    关注

    60

    文章

    2854

    浏览量

    45340
收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    【HarmonyOS 5】鸿蒙页面和组件生命周期函数

    【HarmonyOS 5】鸿蒙页面和组件生命周期函数 ##鸿蒙开发能力 ##HarmonyOS SDK应用服务##鸿蒙金融类应用 (金融理财
    的头像 发表于 07-11 18:24 784次阅读

    【HarmonyOS 5】金融应用开发鸿蒙组件实践

    【HarmonyOS 5】金融应用开发鸿蒙组件实践 ##鸿蒙开发能力 ##HarmonyOS SDK应用服务##
    的头像 发表于 07-11 18:20 743次阅读
    【HarmonyOS 5】金融应用<b class='flag-5'>开发</b><b class='flag-5'>鸿蒙</b><b class='flag-5'>组件</b>实践

    鸿蒙5开发宝藏案例分享---一多开发实例(音乐)

    各位开发者小伙伴们好呀!今天咱们来点硬核干货!最近在鸿蒙文档中心挖到一座“金矿”——官方竟然暗藏了100+实战案例,从分布式架构到交互动效优化应有尽有!这些案例不仅藏着华为工程师的私房技巧,还直接
    的头像 发表于 06-30 11:54 614次阅读

    鸿蒙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

    HarmonyOS实战组件化项目搭建

    前言 鸿蒙应用开发已经成为互联网新的风口,开发鸿蒙软件已经成为今年工作的核心目标。在软件开发过程中,对于复杂度较大,功能较多的软件都会采用
    的头像 发表于 06-09 14:58 504次阅读
    HarmonyOS<b class='flag-5'>实战</b>:<b class='flag-5'>组件</b>化项目搭建

    鸿蒙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