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