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