• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# 拍照(ArkTS)
2<!--Kit: Camera Kit-->
3<!--Subsystem: Multimedia-->
4<!--Owner: @qano-->
5<!--Designer: @leo_ysl-->
6<!--Tester: @xchaosioda-->
7<!--Adviser: @zengyawen-->
8
9拍照是相机的最重要功能之一,拍照模块基于相机复杂的逻辑,为了保证用户拍出的照片质量,在中间步骤可以设置分辨率、闪光灯、焦距、照片质量及旋转角度等信息。
10
11## 开发步骤
12
13详细的API说明请参考[Camera API参考](../../reference/apis-camera-kit/arkts-apis-camera.md)。
14
151. 导入image接口。创建拍照输出流的SurfaceId以及拍照输出的数据,都需要用到系统提供的image接口能力,导入image接口的方法如下。
16
17   ```ts
18   import { image } from '@kit.ImageKit';
19   import { camera } from '@kit.CameraKit';
20   import { fileIo as fs } from '@kit.CoreFileKit';
21   import { photoAccessHelper } from '@kit.MediaLibraryKit';
22   import { BusinessError } from '@kit.BasicServicesKit';
23   ```
24
252. 创建拍照输出流。
26
27   通过[CameraOutputCapability](../../reference/apis-camera-kit/arkts-apis-camera-i.md#cameraoutputcapability)中的photoProfiles属性,可获取当前设备支持的拍照输出流,通过[createPhotoOutput](../../reference/apis-camera-kit/arkts-apis-camera-CameraManager.md#createphotooutput11)方法传入支持的某一个输出流及步骤一获取的SurfaceId创建拍照输出流。
28
29   ```ts
30   function getPhotoOutput(cameraManager: camera.CameraManager, cameraOutputCapability: camera.CameraOutputCapability): camera.PhotoOutput | undefined {
31     let photoProfilesArray: Array<camera.Profile> = cameraOutputCapability.photoProfiles;
32     if (!photoProfilesArray) {
33       console.error("createOutput photoProfilesArray == null || undefined");
34     }
35     let photoOutput: camera.PhotoOutput | undefined = undefined;
36     try {
37       photoOutput = cameraManager.createPhotoOutput(photoProfilesArray[0]);
38     } catch (error) {
39       let err = error as BusinessError;
40       console.error(`Failed to createPhotoOutput. error: ${err}`);
41     }
42     return photoOutput;
43   }
44   ```
45
463. 设置拍照photoAvailable的回调,并将拍照的buffer保存为图片。
47
48    Context获取方式请参考:[获取UIAbility的上下文信息](../../application-models/uiability-usage.md#获取uiability的上下文信息)。
49
50    如需要在图库中看到所保存的图片、视频资源,需要将其保存到媒体库,保存方式请参考:[保存媒体库资源](../medialibrary/photoAccessHelper-savebutton.md)。
51
52    需要在[photoOutput.on('photoAvailable')](../../reference/apis-camera-kit/arkts-apis-camera-PhotoOutput.md#onphotoavailable11)接口获取到buffer时,将buffer在安全控件中保存到媒体库。
53   ```ts
54   function setPhotoOutputCb(photoOutput: camera.PhotoOutput) {
55   // 设置回调之后,调用photoOutput的capture方法,就会将拍照的buffer回传到回调中。
56     photoOutput.on('photoAvailable', (errCode: BusinessError, photo: camera.Photo): void => {
57        console.info('getPhoto start');
58        if (errCode || photo === undefined) {
59          console.error('getPhoto failed, err: ${errCode}');
60          return;
61        }
62        let imageObj: image.Image = photo.main;
63        imageObj.getComponent(image.ComponentType.JPEG, (errCode: BusinessError, component: image.Component): void => {
64          console.info('getComponent start');
65          if (errCode || component === undefined) {
66            console.error('getComponent failed');
67            return;
68          }
69          let buffer: ArrayBuffer;
70          if (component.byteBuffer) {
71            buffer = component.byteBuffer;
72          } else {
73            console.error('byteBuffer is null');
74            return;
75          }
76          // 如需要在图库中看到所保存的图片、视频资源,请使用用户无感的安全控件创建媒体资源。
77
78          // buffer处理结束后需要释放该资源,如果未正确释放资源会导致后续拍照获取不到buffer。
79          imageObj.release();
80        });
81      });
82   }
83   ```
84
854. 参数配置。
86
87   配置相机的参数可以调整拍照的一些功能,包括闪光灯、变焦、焦距等。
88
89   ```ts
90   function configuringSession(photoSession: camera.PhotoSession): void {
91     // 判断设备是否支持闪光灯。
92     let flashStatus: boolean = false;
93     try {
94       flashStatus = photoSession.hasFlash();
95     } catch (error) {
96       let err = error as BusinessError;
97       console.error(`Failed to hasFlash. error: ${err}`);
98     }
99     console.info(`Returned with the flash light support status: ${flashStatus}`);
100     if (flashStatus) {
101       // 判断是否支持自动闪光灯模式。
102       let flashModeStatus: boolean = false;
103       try {
104         let status: boolean = photoSession.isFlashModeSupported(camera.FlashMode.FLASH_MODE_AUTO);
105         flashModeStatus = status;
106       } catch (error) {
107         let err = error as BusinessError;
108         console.error(`Failed to check whether the flash mode is supported. error: ${err}`);
109       }
110       if (flashModeStatus) {
111         // 设置自动闪光灯模式。
112         try {
113           photoSession.setFlashMode(camera.FlashMode.FLASH_MODE_AUTO);
114         } catch (error) {
115           let err = error as BusinessError;
116           console.error(`Failed to set the flash mode. error: ${err}`);
117         }
118       }
119     }
120     // 判断是否支持连续自动变焦模式。
121     let focusModeStatus: boolean = false;
122     try {
123       let status: boolean = photoSession.isFocusModeSupported(camera.FocusMode.FOCUS_MODE_CONTINUOUS_AUTO);
124       focusModeStatus = status;
125     } catch (error) {
126       let err = error as BusinessError;
127       console.error(`Failed to check whether the focus mode is supported. error: ${err}`);
128     }
129     if (focusModeStatus) {
130       // 设置连续自动变焦模式。
131       try {
132         photoSession.setFocusMode(camera.FocusMode.FOCUS_MODE_CONTINUOUS_AUTO);
133       } catch (error) {
134         let err = error as BusinessError;
135         console.error(`Failed to set the focus mode. error: ${err}`);
136       }
137     }
138     // 获取相机支持的可变焦距比范围。
139     let zoomRatioRange: Array<number> = [];
140     try {
141       zoomRatioRange = photoSession.getZoomRatioRange();
142     } catch (error) {
143       let err = error as BusinessError;
144       console.error(`Failed to get the zoom ratio range. error: ${err}`);
145     }
146     if (zoomRatioRange.length <= 0 ) {
147       return;
148     }
149     // 设置可变焦距比。
150     try {
151       photoSession.setZoomRatio(zoomRatioRange[0]);
152     } catch (error) {
153       let err = error as BusinessError;
154       console.error(`Failed to set the zoom ratio value. error: ${err}`);
155     }
156   }
157   ```
158
1595. 触发拍照。
160
161   通过photoOutput的[capture](../../reference/apis-camera-kit/arkts-apis-camera-PhotoOutput.md#capture-2)方法,执行拍照任务。该方法有两个参数,第一个参数为拍照设置参数的setting,setting中可以设置照片的质量和旋转角度,第二参数为回调函数。
162
163   获取拍照旋转角度的方法为,通过[PhotoOutput](../../reference/apis-camera-kit/arkts-apis-camera-PhotoOutput.md)中的[getPhotoRotation](../../reference/apis-camera-kit/arkts-apis-camera-PhotoOutput.md#getphotorotation12)方法获取rotation实际的值。
164
165   > **说明:**
166   >
167   > 图片地理位置信息[Location](../../reference/apis-location-kit/js-apis-geoLocationManager.md#geolocationmanagergetcurrentlocation),使用方法可参考[capture](../../reference/apis-camera-kit/arkts-apis-camera-PhotoOutput.md#capture-3)示例。
168
169   ```ts
170   function capture(captureLocation: camera.Location, photoOutput: camera.PhotoOutput): void {
171     let settings: camera.PhotoCaptureSetting = {
172       quality: camera.QualityLevel.QUALITY_LEVEL_HIGH,  // 设置图片质量高。
173       rotation: camera.ImageRotation.ROTATION_0,  // 设置图片旋转角度的camera.ImageRotation.ROTATION_0是通过说明中获取拍照角度的getPhotoRotation方法获取的值进行设置。
174       location: captureLocation,  // 设置图片地理位置。
175       mirror: false  // 设置镜像使能开关(默认关)。
176     };
177     photoOutput.capture(settings, (err: BusinessError) => {
178       if (err) {
179         console.error(`Failed to capture the photo. error: ${err}`);
180         return;
181       }
182       console.info('Callback invoked to indicate the photo capture request success.');
183     });
184   }
185   ```
186
187## 状态监听
188
189在相机应用开发过程中,可以随时监听拍照输出流状态,包括拍照流开始、拍照帧的开始与结束、拍照输出流的错误。
190
191- 通过注册固定的captureStart回调函数获取监听拍照开始结果,photoOutput创建成功时即可监听,相机设备已经准备开始这次拍照时触发,该事件返回此次拍照的captureId。
192
193  ```ts
194  function onPhotoOutputCaptureStart(photoOutput: camera.PhotoOutput): void {
195    photoOutput.on('captureStartWithInfo', (err: BusinessError, captureStartInfo: camera.CaptureStartInfo) => {
196      if (err !== undefined && err.code !== 0) {
197        return;
198      }
199      console.info(`photo capture started, captureId : ${captureStartInfo.captureId}`);
200    });
201  }
202  ```
203
204- 通过注册固定的captureEnd回调函数获取监听拍照结束结果,photoOutput创建成功时即可监听,该事件返回结果为拍照完全结束后的相关信息[CaptureEndInfo](../../reference/apis-camera-kit/arkts-apis-camera-i.md#captureendinfo)。
205
206  ```ts
207  function onPhotoOutputCaptureEnd(photoOutput: camera.PhotoOutput): void {
208    photoOutput.on('captureEnd', (err: BusinessError, captureEndInfo: camera.CaptureEndInfo) => {
209      if (err !== undefined && err.code !== 0) {
210        return;
211      }
212      console.info(`photo capture end, captureId : ${captureEndInfo.captureId}`);
213      console.info(`frameCount : ${captureEndInfo.frameCount}`);
214    });
215  }
216  ```
217
218- 通过注册固定的captureReady回调函数获取监听可拍下一张结果,photoOutput创建成功时即可监听,当下一张可拍时触发,该事件返回结果为下一张可拍的相关信息。
219
220  ```ts
221  function onPhotoOutputCaptureReady(photoOutput: camera.PhotoOutput): void {
222    photoOutput.on('captureReady', (err: BusinessError) => {
223      if (err !== undefined && err.code !== 0) {
224        return;
225      }
226      console.info(`photo capture ready`);
227    });
228  }
229  ```
230
231- 通过注册固定的error回调函数获取监听拍照输出流的错误结果。回调返回拍照输出接口使用错误时的对应错误码,错误码类型参见[Camera错误码](../../reference/apis-camera-kit/arkts-apis-camera-e.md#cameraerrorcode)。
232
233  ```ts
234  function onPhotoOutputError(photoOutput: camera.PhotoOutput): void {
235    photoOutput.on('error', (error: BusinessError) => {
236      console.error(`Photo output error code: ${error.code}`);
237    });
238  }
239  ```
240