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
    +关注

    关注

    0

    文章

    79

    浏览量

    20751
  • 鸿蒙
    +关注

    关注

    57

    文章

    2301

    浏览量

    42667
收藏 人收藏

    评论

    相关推荐

    鸿蒙Flutter实战:08-如何调试代码

    # 鸿蒙Flutter实战:如何调试代码 ## 1.环境搭建 参考文章[鸿蒙Flutter实战:01-搭建开发环境](https://g
    发表于 10-23 16:29

    鸿蒙Flutter实战:07混合开发

    # 鸿蒙Flutter实战:混合开发 鸿蒙Flutter混合开发主要有两种形式。 ## 1.基于har 将flutter module
    发表于 10-23 16:00

    HarmonyOS实战开发-深度探索与打造个性化自定义组件

    今天分享一下 什么是自定义组件?及其自定义组件实战。 做过前端或者android开发的都知道自定义组件
    发表于 05-08 16:30

    HarmonyOS实战开发-如何使用全局状态保留能力弹窗来实现评论组件

    开发有帮助,我想邀请大家帮我三个小忙: 点赞,转发,有你们的 『点赞和评论』,才是我创造的动力。 关注小编,同时可以期待后续文章ing?,不定期分享原创知识。 更多鸿蒙最新技术知识点,请关注作者博客:鸿蒙
    发表于 05-07 15:06

    OpenHarmony实战开发-如何实现组件动画。

    ArkUI为组件提供了通用的属性动画和转场动画能力的同时,还为一些组件提供了默认的动画效果。例如,List的滑动动效,Button的点击动效,是组件自带的默认动画效果。在组件默认动画效
    的头像 发表于 04-28 15:49 524次阅读
    OpenHarmony<b class='flag-5'>实战</b><b class='flag-5'>开发</b>-如何实现<b class='flag-5'>组件</b>动画。

    鸿蒙实战开发:【相机和媒体库】

    在ArkTS中调用相机拍照和录像,以及如何使用媒体库接口进行媒体文件的增、删、改、查操作。本示例用到了
    的头像 发表于 03-20 16:36 704次阅读
    <b class='flag-5'>鸿蒙</b><b class='flag-5'>实战</b><b class='flag-5'>开发</b>:【<b class='flag-5'>相机</b>和媒体库】

    鸿蒙实战开发学习【FaultLoggerd组件

    Faultloggerd部件是OpenHarmony中C/C++运行时崩溃临时日志的生成及管理模块。面向基于 Rust 开发的部件,Faultloggerd 提供了Rust Panic故障日志生成能力。系统开发者可以在预设的路径下找到故障日志,定位相关问题。
    的头像 发表于 03-17 20:39 437次阅读
    <b class='flag-5'>鸿蒙</b><b class='flag-5'>实战</b><b class='flag-5'>开发</b>学习【FaultLoggerd<b class='flag-5'>组件</b>】

    鸿蒙开发实战:【蓝牙组件

    蓝牙服务组件为设备提供接入与使用Bluetooth的相关接口,包括BLE设备gatt相关的操作,以及BLE广播、扫描等功能。
    的头像 发表于 03-13 17:27 607次阅读

    鸿蒙开发实战:【性能调优组件

    性能调优组件包含系统和应用调优框架,旨在为开发者提供一套性能调优平台,可以用来分析内存、性能等问题
    的头像 发表于 03-13 15:12 369次阅读
    <b class='flag-5'>鸿蒙</b><b class='flag-5'>开发</b><b class='flag-5'>实战</b>:【性能调优<b class='flag-5'>组件</b>】

    鸿蒙实战项目开发:【短信服务】

    、OpenHarmony 多媒体技术、Napi组件、OpenHarmony内核、Harmony南向开发鸿蒙项目实战等等)鸿蒙(Harmon
    发表于 03-03 21:29

    鸿蒙ArkUI开发-Tabs组件的使用

    鸿蒙ArkUI开发-Tabs组件的使用
    的头像 发表于 01-19 16:01 1682次阅读
    <b class='flag-5'>鸿蒙</b>ArkUI<b class='flag-5'>开发</b>-Tabs<b class='flag-5'>组件</b>的使用

    鸿蒙开发实战-(ArkUI)List组件和Grid组件的使用

    一系列相同宽度的列表项,连续、多行呈现同类数据,例如图片和文本。常见的列表有线性列表(List列表)和网格布局(Grid列表): 为了帮助开发者构建包含列表的应用,ArkUI提供了List组件和Grid
    发表于 01-18 20:18

    鸿蒙开发OpenHarmony组件复用案例

    ) } }, item => item) } } } 本文主要是对鸿蒙开发基础当中的OpenHarmony技术组件复用示例, 更多鸿蒙开发
    发表于 01-15 17:37

    鸿蒙开发基础-Web组件之cookie操作

    }) ... } ... 本文章主要是对鸿蒙开发当中ArkTS语言的基础应用实战,Web组件里的cookie操作。更多的鸿蒙应用
    发表于 01-14 21:31

    鸿蒙基础开发实战-(ArkTS)像素转换

    的使用。通过像素转换案例,向开发者讲解了如何使用像素单位设置组件的尺寸、字体的大小以及不同像素单位之间的转换方法。更多鸿蒙4.0的学习,可以前往主页学习或前往《鸿蒙4.0
    发表于 01-11 16:53