相机组件支持相机业务的开发,开发者可以通过已开放的接口实现相机硬件的访问、操作和新功能开发,最常见的操作如:预览、拍照和录像等。
基本概念
- 拍照
此功能用于拍摄采集照片。 - 预览
此功能用于在开启相机后,在缓冲区内重复采集摄像帧,支持在拍照或录像前进行摄像帧预览显示。 - 录像
此功能用于在开始录像后和结束录像前的时间段内,在缓冲区内重复采集摄像帧,支持视频录制。
图 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
+关注
关注
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实战开发-如何使用全局状态保留能力弹窗来实现评论组件。
开发有帮助,我想邀请大家帮我三个小忙:
点赞,转发,有你们的 『点赞和评论』,才是我创造的动力。
关注小编,同时可以期待后续文章ing?,不定期分享原创知识。
更多鸿蒙最新技术知识点,请关注作者博客:鸿蒙
发表于 05-07 15:06
OpenHarmony实战开发-如何实现组件动画。
ArkUI为组件提供了通用的属性动画和转场动画能力的同时,还为一些组件提供了默认的动画效果。例如,List的滑动动效,Button的点击动效,是组件自带的默认动画效果。在组件默认动画效
鸿蒙实战开发学习【FaultLoggerd组件】
Faultloggerd部件是OpenHarmony中C/C++运行时崩溃临时日志的生成及管理模块。面向基于 Rust 开发的部件,Faultloggerd 提供了Rust Panic故障日志生成能力。系统开发者可以在预设的路径下找到故障日志,定位相关问题。
鸿蒙开发实战:【蓝牙组件】
蓝牙服务组件为设备提供接入与使用Bluetooth的相关接口,包括BLE设备gatt相关的操作,以及BLE广播、扫描等功能。
鸿蒙实战项目开发:【短信服务】
、OpenHarmony 多媒体技术、Napi组件、OpenHarmony内核、Harmony南向开发、鸿蒙项目实战等等)鸿蒙(Harmon
发表于 03-03 21:29
鸿蒙开发实战-(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
评论