前言:
相机组件支持相机业务的开发,开发者可以通过已开放的接口实现相机硬件的访问、操作和新功能开发,最常见的操作如:预览、拍照和录像等。
基本概念
-
拍照
此功能用于拍摄采集照片。
-
预览
此功能用于在开启相机后,在缓冲区内重复采集摄像帧,支持在拍照或录像前进行摄像帧预览显示。
-
录像
此功能用于在开始录像后和结束录像前的时间段内,在缓冲区内重复采集摄像帧,支持视频录制。
点击领取→纯血版全套鸿蒙HarmonyOS学习资料希望这一份鸿蒙学习资料能够给大家带来帮助,有需要的小伙伴自行领取,限时开源,先到先得
目录
仓目录结构如下:
/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();
最后
有很多小伙伴不知道学习哪些鸿蒙开发技术?不知道需要重点掌握哪些鸿蒙应用开发知识点?但是又不知道从哪里下手,而且学习时频繁踩坑,最终浪费大量时间。所以本人整理了一些比较合适的鸿蒙(HarmonyOS NEXT)学习路径和一些资料的整理供小伙伴学习
点击领取→纯血鸿蒙Next全套最新学习资料希望这一份鸿蒙学习资料能够给大家带来帮助,有需要的小伙伴自行领取~~
一、鸿蒙(HarmonyOS NEXT)最新学习路线
有了路线图,怎么能没有学习资料呢,小编也准备了一份联合鸿蒙官方发布笔记整理收纳的一套系统性的鸿蒙(OpenHarmony )学习手册(共计1236页)与鸿蒙(OpenHarmony )开发入门教学视频,内容包含:(ArkTS、ArkUI开发组件、Stage模型、多端部署、分布式应用开发、音频、视频、WebGL、OpenHarmony多媒体技术、Napi组件、OpenHarmony内核、Harmony南向开发、鸿蒙项目实战等等)鸿蒙(HarmonyOS NEXT)…等技术知识点。
获取以上完整版高清,请点击→纯血版全套鸿蒙HarmonyOS学习资料
二、HarmonyOS Next 最新全套视频教程
三、《鸿蒙 (OpenHarmony)开发基础到实战手册》
OpenHarmony北向、南向开发环境搭建
四、大厂面试必问面试题
五、鸿蒙南向开发技术
六、鸿蒙APP开发必备
完整鸿蒙HarmonyOS学习资料,请点击→纯血版全套鸿蒙HarmonyOS学习资料
总结
总的来说,对于大家来说ye是一个挑战,也是一个机会。只有积极应对变化,不断学习和提升自己,他们才能在这个变革的时代中立于不败之地。