1# Camera组件<a name="ZH-CN_TOPIC_0000001101564782"></a>
2
3- [Camera组件<a name="ZH-CN_TOPIC_0000001101564782"></a>](#camera组件)
4  - [简介<a name="section11660541593"></a>](#简介)
5    - [基本概念<a name="sectionbasicconcepts"></a>](#基本概念)
6  - [目录<a name="section176641621345"></a>](#目录)
7  - [使用说明<a name="section45377346241"></a>](#使用说明)
8    - [拍照<a name="section2071191842718"></a>](#拍照)
9    - [开始和停止预览<a name="section2094314213271"></a>](#开始和停止预览)
10    - [视频录像<a name="section1983913118271"></a>](#视频录像)
11    - [切换多个照相机设备<a name="sectionswitchcamera"></a>](#切换多个照相机设备)
12    - [设置闪光灯<a name="sectionsetflash"></a>](#设置闪光灯)
13  - [相关仓<a name="section16511040154318"></a>](#相关仓)
14
15## 简介<a name="section11660541593"></a>
16
17相机组件支持相机业务的开发,开发者可以通过已开放的接口实现相机硬件的访问、操作和新功能开发,最常见的操作如:预览、拍照和录像等。
18
19### 基本概念<a name="sectionbasicconcepts"></a>
20
21-   拍照
22
23    此功能用于拍摄采集照片。
24
25-   预览
26
27    此功能用于在开启相机后,在缓冲区内重复采集摄像帧,支持在拍照或录像前进行摄像帧预览显示。
28
29-   录像
30
31    此功能用于在开始录像后和结束录像前的时间段内,在缓冲区内重复采集摄像帧,支持视频录制。
32
33**图 1**  相机组件架构图<a name="fig310889397"></a>
34
35![](figures/camera-architecture-zh.png "camera-architecture-zh")
36
37## 目录<a name="section176641621345"></a>
38
39仓目录结构如下:
40
41```
42/foundation/multimedia/camera_framework   # 相机组件业务代码
43├── frameworks                           # 框架代码
44│   ├── native                           # 内部接口实现
45│   │   ├── camera                       # 相机框架实现
46│   │   └── metadata                     # 元数据实现
47│   └── js                               # 外部接口实现
48│       └── camera_napi                  # 相机NAPI实现
49├── interfaces                           # 接口代码
50│   ├── inner_api                        # 内部接口
51│   └── kits                             # 外部接口
52├── LICENSE                              # 许可证文件
53├── ohos.build                           # 构建文件
54├── sa_profile                           # 服务配置文件
55└── services                             # 服务代码
56    ├── camera_service                   # 相机服务实现
57    └── etc                              # 相机服务配置
58```
59
60## 使用说明<a name="section45377346241"></a>
61
62### 拍照<a name="section2071191842718"></a>
63
64拍照的步骤:
65
661.  创建缓冲区消费者端监听器(CaptureSurfaceListener)以保存图像。
67    ```
68    class CaptureSurfaceListener : public IBufferConsumerListener {
69    public:
70        int32_t mode_;
71        sptr<Surface> surface_;
72
73        void OnBufferAvailable() override
74        {
75            int32_t flushFence = 0;
76            int64_t timestamp = 0;
77            OHOS::Rect damage; // initialize the damage
78
79            OHOS::sptr<OHOS::SurfaceBuffer> buffer = nullptr;
80            surface_->AcquireBuffer(buffer, flushFence, timestamp, damage);
81            if (buffer != nullptr) {
82                void* addr = buffer->GetVirAddr();
83                int32_t size = buffer->GetSize();
84
85                // Save the buffer(addr) to a file.
86
87                surface_->ReleaseBuffer(buffer, -1);
88            }
89        }
90    };
91    ```
92
932.  获取相机管理器实例并获取相机对象列表。
94
95    ```
96    sptr<CameraManager> camManagerObj = CameraManager::GetInstance();
97    std::vector<sptr<CameraInfo>> cameraObjList = camManagerObj->GetCameras();
98    ```
99
1003.  使用相机对象创建相机输入来打开相机。
101
102    ```
103    sptr<CaptureInput> cameraInput = camManagerObj->CreateCameraInput(cameraObjList[0]);
104    ```
105
1064.  创建采集会话。
107
108    ```
109    sptr<CaptureSession> captureSession = camManagerObj->CreateCaptureSession();
110    ```
111
1125.  开始配置采集会话。
113
114    ```
115    int32_t result = captureSession->BeginConfig();
116    ```
117
1186.  将相机输入添加到采集会话。
119
120    ```
121    result = captureSession->AddInput(cameraInput);
122    ```
123
1247.  创建消费者 Surface 并注册监听器以监听缓冲区更新。拍照的宽和高可以配置为所支持的 1280x960 分辨率。
125
126    ```
127    sptr<Surface> photoSurface = Surface::CreateSurfaceAsConsumer();
128    int32_t photoWidth = 1280;
129    int32_t photoHeight = 960;
130    photoSurface->SetDefaultWidthAndHeight(photoWidth, photoHeight);
131    photoSurface->SetUserData(CameraManager::surfaceFormat, std::to_string(OHOS_CAMERA_FORMAT_JPEG));
132    sptr<CaptureSurfaceListener> capturelistener = new(std::nothrow) CaptureSurfaceListener();
133    capturelistener->mode_ = MODE_PHOTO;
134    capturelistener->surface_ = photoSurface;
135    photoSurface->RegisterConsumerListener((sptr<IBufferConsumerListener> &)capturelistener);
136    ```
137
1388.  使用上面创建的 Surface 创建拍照输出。
139
140    ```
141    sptr<CaptureOutput> photoOutput = camManagerObj->CreatePhotoOutput(photoSurface);
142    ```
143
1449.  将拍照输出添加到采集会话。
145
146    ```
147    result = captureSession->AddOutput(photoOutput);
148    ```
149
15010. 将配置提交到采集会话。
151
152    ```
153    result = captureSession->CommitConfig();
154    ```
155
15611. 拍摄照片。
157
158    ```
159    result = ((sptr<PhotoOutput> &)photoOutput)->Capture();
160    ```
161
16212. 释放采集会话资源。
163
164    ```
165    captureSession->Release();
166    ```
167
16813. 释放相机输入关闭相机。
169
170    ```
171    cameraInput->Release();
172    ```
173
174### 开始和停止预览<a name="section2094314213271"></a>
175
176开始和停止预览的步骤:
177
1781.  获取相机管理器实例并获取相机对象列表。
179
180    ```
181    sptr<CameraManager> camManagerObj = CameraManager::GetInstance();
182    std::vector<sptr<CameraInfo>> cameraObjList = camManagerObj->GetCameras();
183    ```
184
1852.  使用相机对象创建相机输入来打开相机。
186
187    ```
188    sptr<CaptureInput> cameraInput = camManagerObj->CreateCameraInput(cameraObjList[0]);
189    ```
190
1913.  创建采集会话。
192
193    ```
194    sptr<CaptureSession> captureSession = camManagerObj->CreateCaptureSession();
195    ```
196
1974.  开始配置采集会话。
198
199    ```
200    int32_t result = captureSession->BeginConfig();
201    ```
202
2035.  将相机输入添加到采集会话。
204
205    ```
206    result = captureSession->AddInput(cameraInput);
207    ```
208
2096.  使用从窗口管理器获得的 Surface 创建预览输出用以在显示上渲染。预览的宽和高可以配置为所支持的 640x480 或 832x480 分辨率,如果想保存到文件,可以按照拍照流程提到步骤,创建 Surface,注册监听器以监听缓冲区更新。
210
211    ```
212    int32_t previewWidth = 640;
213    int32_t previewHeight = 480;
214    previewSurface->SetUserData(CameraManager::surfaceFormat, std::to_string(OHOS_CAMERA_FORMAT_YCRCB_420_SP));
215    sptr<CaptureOutput> previewOutput = camManagerObj->CreateCustomPreviewOutput(previewSurface, previewWidth, previewHeight);
216    ```
217
2187.  将预览输出添加到采集会话。
219
220    ```
221    result = captureSession->AddOutput(previewOutput);
222    ```
223
2248.  将配置提交到采集会话。
225
226    ```
227    result = captureSession->CommitConfig();
228    ```
229
2309.  开始预览。
231
232    ```
233    result = captureSession->Start();
234    ```
235
23610. 需要时停止预览。
237
238    ```
239    result = captureSession->Stop();
240    ```
241
24211. 释放采集会话资源。
243
244    ```
245    captureSession->Release();
246    ```
247
24812. 释放相机输入关闭相机。
249
250    ```
251    cameraInput->Release();
252    ```
253
254### 视频录像<a name="section1983913118271"></a>
255
256视频录像的步骤:
257
2581.  获取相机管理器实例并获取相机对象列表。
259
260    ```
261    sptr<CameraManager> camManagerObj = CameraManager::GetInstance();
262    std::vector<sptr<CameraInfo>> cameraObjList = camManagerObj->GetCameras();
263    ```
264
2652.  使用相机对象创建相机输入来打开相机。
266
267    ```
268    sptr<CaptureInput> cameraInput = camManagerObj->CreateCameraInput(cameraObjList[0]);
269    ```
270
2713.  创建采集会话。
272
273    ```
274    sptr<CaptureSession> captureSession = camManagerObj->CreateCaptureSession();
275    ```
276
2774.  开始配置采集会话。
278
279    ```
280    int32_t result = captureSession->BeginConfig();
281    ```
282
2835.  将相机输入添加到采集会话。
284
285    ```
286    result = captureSession->AddInput(cameraInput);
287    ```
288
2896.  通过 Surface 创建一个视频输出,来与音频合成并保存到文件,Surface 通过 Recoder 获取。如果想仅保存视频缓冲数据到文件里,可以按照拍照流程提到步骤,创建 Surface,注册监听器以监听缓冲区更新。录像的分辨率可以在录制器内配置为所支持的 1280x720 或 640x360 分辨率。
290
291    ```
292    videoSurface->SetUserData(CameraManager::surfaceFormat, std::to_string(OHOS_CAMERA_FORMAT_YCRCB_420_SP));
293    sptr<CaptureOutput> videoOutput = camManagerObj->CreateVideoOutput(videoSurface);
294    ```
295
2967.  将视频输出添加到采集会话。
297
298    ```
299    result = captureSession->AddOutput(videoOutput);
300    ```
301
3028.  将配置提交到采集会话。
303
304    ```
305    result = captureSession->CommitConfig();
306    ```
307
3089.  开始视频录制。
309
310    ```
311    result = ((sptr<VideoOutput> &)videoOutput)->Start();
312    ```
313
31410. 需要时停止录制。
315
316    ```
317    result = ((sptr<VideoOutput> &)videoOutput)->Stop();
318    ```
319
32011. 释放采集会话的资源。
321
322    ```
323    captureSession->Release();
324    ```
325
32612. 释放相机输入关闭相机。
327
328    ```
329    cameraInput->Release();
330    ```
331
332### 切换多个照相机设备<a name="sectionswitchcamera"></a>
333
334以下演示如何切换多个照相机设备。最初在采集会话中有一个视频输出(video output)。如果用户想要切换其他 照相机,现存的相机输入和输出需要先移除并加入新的相机输入和输出(示例中使用的是photo output)。
335
3361.  获取相机管理器实例并获取相机对象列表。
337
338    ```
339    sptr<CameraManager> camManagerObj = CameraManager::GetInstance();
340    std::vector<sptr<CameraInfo>> cameraObjList = camManagerObj->GetCameras();
341    ```
342
3432.  使用相机对象创建相机输入来打开相机。
344
345    ```
346    sptr<CaptureInput> cameraInput = camManagerObj->CreateCameraInput(cameraObjList[0]);
347    ```
348
3493.  创建采集会话。
350
351    ```
352    sptr<CaptureSession> captureSession = camManagerObj->CreateCaptureSession();
353    ```
354
3554.  开始配置采集会话。
356
357    ```
358    int32_t result = captureSession->BeginConfig()
359    ```
360
3615.  将相机输入添加到采集会话。
362
363    ```
364    result = captureSession->AddInput(cameraInput);
365    ```
366
3676.  通过Surface创建一个视频输出。
368
369    ```
370    sptr<CaptureOutput> videoOutput = camManagerObj->CreateVideoOutput(videoSurface);
371    ```
372
3737.  将视频输出添加到采集会话。
374
375    ```
376    result = captureSession->AddOutput(videoOutput);
377    ```
378
3798.  将配置提交到采集会话。
380
381    ```
382    result = captureSession->CommitConfig();
383    ```
384
3859.  开始录制视频。
386
387    ```
388    result = ((sptr<VideoOutput> &)videoOutput)->Start();
389    ```
390
39110. 需要时停止录制。
392
393    ```
394    result = ((sptr<VideoOutput> &)videoOutput)->Stop();
395    ```
396
39711. 重新配置会话并移除相机输入和输出。
398
399    ```
400    int32_t result = captureSession->BeginConfig();
401    ```
402
40312. 在新的会话配置中移除相机输入。
404
405    ```
406    int32_t result = captureSession->RemoveInput(cameraInput);
407    ```
408
40913. 同样移除相机输出。
410
411    ```
412    int32_t result = captureSession->RemoveOutut(videoOutput);
413    ```
414
41514. 创建新的相机输入,并把它添加到采集会话。
416
417    ```
418    sptr<CaptureInput> cameraInput2 = camManagerObj->CreateCameraInput(cameraObjList[1]);
419    result = captureSession->AddInput(cameraInput2);
420    ```
421
42215. 创建拍照输出,成功创建后将拍照输出添加到采集会话。创建消费者 Surface 并注册监听器以监听新的拍照输出缓冲区更新。这个 Surface 用于新创建的拍照输出。
423
424    ```
425    // Get the surface
426    sptr<Surface> photoSurface = Surface::CreateSurfaceAsConsumer();
427    int32_t photoWidth = 1280;
428    int32_t photoHeight = 960;
429    photoSurface->SetDefaultWidthAndHeight(photoWidth, photoHeight);
430    photoSurface->SetUserData(CameraManager::surfaceFormat, std::to_string(OHOS_CAMERA_FORMAT_JPEG));
431    sptr<CaptureSurfaceListener> capturelistener = new(std::nothrow) CaptureSurfaceListener();
432    capturelistener->mode_ = MODE_PHOTO;
433    capturelistener->surface_ = photoSurface;
434    photoSurface->RegisterConsumerListener((sptr<IBufferConsumerListener> &)capturelistener);
435
436    // Create the Photo Output
437    sptr<CaptureOutput> photoOutput = camManagerObj->CreatePhotoOutput(photoSurface);
438
439    // Add the output to the capture session
440    result = captureSession->AddOutput(photoOutput);
441    ```
442
44316. 将配置提交到采集会话。
444
445    ```
446    result = captureSession->CommitConfig();
447    ```
448
44917. 释放被移出会话的相机输入。
450
451    ```
452    cameraInput->Release();
453    ```
454
45518. 拍摄照片。
456
457    ```
458    result = ((sptr<PhotoOutput> &)photoOutput)->Capture();
459    ```
460
46119. 释放采集会话资源。
462
463    ```
464    captureSession->Release();
465    ```
466
46720. 释放相机输入关闭相机。
468
469    ```
470    cameraInput2->Release();
471    ```
472
473### 设置闪光灯<a name="sectionsetflash"></a>
474
475拍照和录像前可以在相机输入里设置闪光灯。
476
4771.  在照相中设置闪光灯。
478
479    ```
480    cameraInput->LockForControl();
481    cameraInput->SetFlashMode(OHOS_CAMERA_FLASH_MODE_OPEN);
482    cameraInput->UnlockForControl();
483    ```
484
4852.  在录像中设置闪光灯。
486
487    ```
488    cameraInput->LockForControl();
489    cameraInput->SetFlashMode(OHOS_CAMERA_FLASH_MODE_ALWAYS_OPEN);
490    cameraInput->UnlockForControl();
491    ```
492
4933.  关闭闪光灯。
494
495    ```
496    cameraInput->LockForControl();
497    cameraInput->SetFlashMode(OHOS_CAMERA_FLASH_MODE_CLOSE);
498    cameraInput->UnlockForControl();
499    ```
500
501## 相关仓<a name="section16511040154318"></a>
502
503[multimedia\_camera\_framework](https://gitee.com/openharmony/multimedia_camera_framework)
504
505