1# 拍照 2 3拍照是相机的最重要功能之一,拍照模块基于相机复杂的逻辑,为了保证用户拍出的照片质量,在中间步骤可以设置分辨率、闪光灯、焦距、照片质量及旋转角度等信息。 4 5## 开发步骤 6 7详细的API说明请参考[Camera API参考](../reference/apis/js-apis-camera.md)。 8 91. 导入image接口。创建拍照输出流的SurfaceId以及拍照输出的数据,都需要用到系统提供的image接口能力,导入image接口的方法如下。 10 11 ```ts 12 import image from '@ohos.multimedia.image'; 13 import camera from '@ohos.multimedia.camera'; 14 import { BusinessError } from '@ohos.base'; 15 ``` 16 172. 获取SurfaceId。 18 19 通过image的createImageReceiver方法创建ImageReceiver实例,再通过实例的getReceivingSurfaceId方法获取SurfaceId,与拍照输出流相关联,获取拍照输出流的数据。 20 21 ```ts 22 async function getImageReceiverSurfaceId(): Promise<string | undefined> { 23 let photoSurfaceId: string | undefined = undefined; 24 let receiver: image.ImageReceiver = image.createImageReceiver(640, 480, 4, 8); 25 console.info('before ImageReceiver check'); 26 if (receiver !== undefined) { 27 console.info('ImageReceiver is ok'); 28 photoSurfaceId = await receiver.getReceivingSurfaceId(); 29 console.info(`ImageReceived id: ${JSON.stringify(photoSurfaceId)}`); 30 } else { 31 console.info('ImageReceiver is not ok'); 32 } 33 return photoSurfaceId; 34 } 35 ``` 36 373. 创建拍照输出流。 38 39 通过CameraOutputCapability类中的photoProfiles()方法,可获取当前设备支持的拍照输出流,通过createPhotoOutput()方法传入支持的某一个输出流及步骤一获取的SurfaceId创建拍照输出流。 40 41 ```ts 42 function getPhotoOutput(cameraManager: camera.CameraManager, cameraOutputCapability: camera.CameraOutputCapability, photoSurfaceId: string): camera.PhotoOutput | undefined { 43 let photoProfilesArray: Array<camera.Profile> = cameraOutputCapability.photoProfiles; 44 if (!photoProfilesArray) { 45 console.error("createOutput photoProfilesArray == null || undefined"); 46 } 47 let photoOutput: camera.PhotoOutput | undefined; 48 try { 49 photoOutput = cameraManager.createPhotoOutput(photoProfilesArray[0], photoSurfaceId); 50 } catch (error) { 51 let err = error as BusinessError; 52 console.error(`Failed to createPhotoOutput. error: ${JSON.stringify(err)}`); 53 } 54 return photoOutput; 55 } 56 ``` 57 584. 参数配置。 59 60 配置相机的参数可以调整拍照的一些功能,包括闪光灯、变焦、焦距等。 61 62 ```ts 63 function configuringSession(captureSession: camera.CaptureSession): void { 64 // 判断设备是否支持闪光灯 65 let flashStatus: boolean = false; 66 try { 67 flashStatus = captureSession.hasFlash(); 68 } catch (error) { 69 let err = error as BusinessError; 70 console.error(`Failed to hasFlash. error: ${JSON.stringify(err)}`); 71 } 72 console.info(`Promise returned with the flash light support status: ${flashStatus}`); 73 if (flashStatus) { 74 // 判断是否支持自动闪光灯模式 75 let flashModeStatus: boolean = false; 76 try { 77 let status: boolean = captureSession.isFlashModeSupported(camera.FlashMode.FLASH_MODE_AUTO); 78 flashModeStatus = status; 79 } catch (error) { 80 let err = error as BusinessError; 81 console.error(`Failed to check whether the flash mode is supported. error: ${JSON.stringify(err)}`); 82 } 83 if (flashModeStatus) { 84 // 设置自动闪光灯模式 85 try { 86 captureSession.setFlashMode(camera.FlashMode.FLASH_MODE_AUTO); 87 } catch (error) { 88 let err = error as BusinessError; 89 console.error(`Failed to set the flash mode. error: ${JSON.stringify(err)}`); 90 } 91 } 92 } 93 // 判断是否支持连续自动变焦模式 94 let focusModeStatus: boolean = false; 95 try { 96 let status: boolean = captureSession.isFocusModeSupported(camera.FocusMode.FOCUS_MODE_CONTINUOUS_AUTO); 97 focusModeStatus = status; 98 } catch (error) { 99 let err = error as BusinessError; 100 console.error(`Failed to check whether the focus mode is supported. error: ${JSON.stringify(err)}`); 101 } 102 if (focusModeStatus) { 103 // 设置连续自动变焦模式 104 try { 105 captureSession.setFocusMode(camera.FocusMode.FOCUS_MODE_CONTINUOUS_AUTO); 106 } catch (error) { 107 let err = error as BusinessError; 108 console.error(`Failed to set the focus mode. error: ${JSON.stringify(err)}`); 109 } 110 } 111 // 获取相机支持的可变焦距比范围 112 let zoomRatioRange: Array<number> = []; 113 try { 114 zoomRatioRange = captureSession.getZoomRatioRange(); 115 } catch (error) { 116 let err = error as BusinessError; 117 console.error(`Failed to get the zoom ratio range. error: ${JSON.stringify(err)}`); 118 } 119 if (zoomRatioRange.length <= 0 ) { 120 return; 121 } 122 // 设置可变焦距比 123 try { 124 captureSession.setZoomRatio(zoomRatioRange[0]); 125 } catch (error) { 126 let err = error as BusinessError; 127 console.error(`Failed to set the zoom ratio value. error: ${JSON.stringify(err)}`); 128 } 129 } 130 ``` 131 1325. 触发拍照。 133 134 通过photoOutput类的capture()方法,执行拍照任务。该方法有两个参数,第一个参数为拍照设置参数的setting,setting中可以设置照片的质量和旋转角度,第二参数为回调函数。 135 136 ```ts 137 function capture(captureLocation: camera.Location, photoOutput: camera.PhotoOutput): void { 138 let settings: camera.PhotoCaptureSetting = { 139 quality: camera.QualityLevel.QUALITY_LEVEL_HIGH, // 设置图片质量高 140 rotation: camera.ImageRotation.ROTATION_0, // 设置图片旋转角度0 141 location: captureLocation, // 设置图片地理位置 142 mirror: false // 设置镜像使能开关(默认关) 143 }; 144 photoOutput.capture(settings, (err: BusinessError) => { 145 if (err) { 146 console.error(`Failed to capture the photo. error: ${JSON.stringify(err)}`); 147 return; 148 } 149 console.info('Callback invoked to indicate the photo capture request success.'); 150 }); 151 } 152 ``` 153 154## 状态监听 155 156在相机应用开发过程中,可以随时监听拍照输出流状态,包括拍照流开始、拍照帧的开始与结束、拍照输出流的错误。 157 158- 通过注册固定的captureStart回调函数获取监听拍照开始结果,photoOutput创建成功时即可监听,拍照第一次曝光时触发,该事件返回此次拍照的captureId。 159 160 ```ts 161 function onPhotoOutputCaptureStart(photoOutput: camera.PhotoOutput): void { 162 photoOutput.on('captureStart', (err: BusinessError, captureId: number) => { 163 console.info(`photo capture stated, captureId : ${captureId}`); 164 }); 165 } 166 ``` 167 168- 通过注册固定的captureEnd回调函数获取监听拍照结束结果,photoOutput创建成功时即可监听,该事件返回结果为拍照完全结束后的相关信息[CaptureEndInfo](../reference/apis/js-apis-camera.md#captureendinfo)。 169 170 ```ts 171 function onPhotoOutputCaptureEnd(photoOutput: camera.PhotoOutput): void { 172 photoOutput.on('captureEnd', (err: BusinessError, captureEndInfo: camera.CaptureEndInfo) => { 173 console.info(`photo capture end, captureId : ${captureEndInfo.captureId}`); 174 console.info(`frameCount : ${captureEndInfo.frameCount}`); 175 }); 176 } 177 ``` 178 179- 通过注册固定的error回调函数获取监听拍照输出流的错误结果。callback返回拍照输出接口使用错误时的对应错误码,错误码类型参见[CameraErrorCode](../reference/apis/js-apis-camera.md#cameraerrorcode)。 180 181 ```ts 182 function onPhotoOutputError(photoOutput: camera.PhotoOutput): void { 183 photoOutput.on('error', (error: BusinessError) => { 184 console.info(`Photo output error code: ${error.code}`); 185 }); 186 } 187 ``` 188