1# 拍照实现方案 2 3## 开发流程 4 5在获取到相机支持的输出流能力后,开始创建拍照流,开发流程如下。 6 7 8 9## 完整示例 10[BaseContext获取方式](../reference/apis/js-apis-inner-application-baseContext.md)。 11```ts 12import camera from '@ohos.multimedia.camera'; 13import image from '@ohos.multimedia.image'; 14import { BusinessError } from '@ohos.base'; 15import common from '@ohos.app.ability.common'; 16 17async function cameraShootingCase(baseContext: common.BaseContext, surfaceId: string): Promise<void> { 18 // 创建CameraManager对象 19 let cameraManager: camera.CameraManager = camera.getCameraManager(baseContext); 20 if (!cameraManager) { 21 console.error("camera.getCameraManager error"); 22 return; 23 } 24 // 监听相机状态变化 25 cameraManager.on('cameraStatus', (err: BusinessError, cameraStatusInfo: camera.CameraStatusInfo) => { 26 console.info(`camera : ${cameraStatusInfo.camera.cameraId}`); 27 console.info(`status: ${cameraStatusInfo.status}`); 28 }); 29 30 // 获取相机列表 31 let cameraArray: Array<camera.CameraDevice> = cameraManager.getSupportedCameras(); 32 if (cameraArray.length <= 0) { 33 console.error("cameraManager.getSupportedCameras error"); 34 return; 35 } 36 37 for (let index = 0; index < cameraArray.length; index++) { 38 console.info('cameraId : ' + cameraArray[index].cameraId); // 获取相机ID 39 console.info('cameraPosition : ' + cameraArray[index].cameraPosition); // 获取相机位置 40 console.info('cameraType : ' + cameraArray[index].cameraType); // 获取相机类型 41 console.info('connectionType : ' + cameraArray[index].connectionType); // 获取相机连接类型 42 } 43 44 // 创建相机输入流 45 let cameraInput: camera.CameraInput | undefined = undefined; 46 try { 47 cameraInput = cameraManager.createCameraInput(cameraArray[0]); 48 } catch (error) { 49 let err = error as BusinessError; 50 console.error('Failed to createCameraInput errorCode = ' + err.code); 51 } 52 if (cameraInput === undefined) { 53 return; 54 } 55 56 // 监听cameraInput错误信息 57 let cameraDevice: camera.CameraDevice = cameraArray[0]; 58 cameraInput.on('error', cameraDevice, (error: BusinessError) => { 59 console.info(`Camera input error code: ${error.code}`); 60 }) 61 62 // 打开相机 63 await cameraInput.open(); 64 65 // 获取相机设备支持的输出流能力 66 let cameraOutputCap: camera.CameraOutputCapability = cameraManager.getSupportedOutputCapability(cameraArray[0]); 67 if (!cameraOutputCap) { 68 console.error("cameraManager.getSupportedOutputCapability error"); 69 return; 70 } 71 console.info("outputCapability: " + JSON.stringify(cameraOutputCap)); 72 73 let previewProfilesArray: Array<camera.Profile> = cameraOutputCap.previewProfiles; 74 if (!previewProfilesArray) { 75 console.error("createOutput previewProfilesArray == null || undefined"); 76 } 77 78 let photoProfilesArray: Array<camera.Profile> = cameraOutputCap.photoProfiles; 79 if (!photoProfilesArray) { 80 console.error("createOutput photoProfilesArray == null || undefined"); 81 } 82 83 // 创建预览输出流,其中参数 surfaceId 参考上文 XComponent 组件,预览流为XComponent组件提供的surface 84 let previewOutput: camera.PreviewOutput | undefined = undefined; 85 try { 86 previewOutput = cameraManager.createPreviewOutput(previewProfilesArray[0], surfaceId); 87 } catch (error) { 88 let err = error as BusinessError; 89 console.error(`Failed to create the PreviewOutput instance. error code: ${err.code}`); 90 } 91 if (previewOutput === undefined) { 92 return; 93 } 94 // 监听预览输出错误信息 95 previewOutput.on('error', (error: BusinessError) => { 96 console.info(`Preview output error code: ${error.code}`); 97 }); 98 99 // 创建ImageReceiver对象,并设置照片参数:分辨率大小是根据前面 photoProfilesArray 获取的当前设备所支持的拍照分辨率大小去设置 100 let imageReceiver: image.ImageReceiver = image.createImageReceiver(1920, 1080, 4, 8); 101 // 获取照片显示SurfaceId 102 let photoSurfaceId: string = await imageReceiver.getReceivingSurfaceId(); 103 // 创建拍照输出流 104 let photoOutput: camera.PhotoOutput | undefined = undefined; 105 try { 106 photoOutput = cameraManager.createPhotoOutput(photoProfilesArray[0], photoSurfaceId); 107 } catch (error) { 108 let err = error as BusinessError; 109 console.error('Failed to createPhotoOutput errorCode = ' + err.code); 110 } 111 if (photoOutput === undefined) { 112 return; 113 } 114 //创建会话 115 let captureSession: camera.CaptureSession | undefined = undefined; 116 try { 117 captureSession = cameraManager.createCaptureSession(); 118 } catch (error) { 119 let err = error as BusinessError; 120 console.error('Failed to create the CaptureSession instance. errorCode = ' + err.code); 121 } 122 if (captureSession === undefined) { 123 return; 124 } 125 // 监听session错误信息 126 captureSession.on('error', (error: BusinessError) => { 127 console.info(`Capture session error code: ${error.code}`); 128 }); 129 130 // 开始配置会话 131 try { 132 captureSession.beginConfig(); 133 } catch (error) { 134 let err = error as BusinessError; 135 console.error('Failed to beginConfig. errorCode = ' + err.code); 136 } 137 138 // 向会话中添加相机输入流 139 try { 140 captureSession.addInput(cameraInput); 141 } catch (error) { 142 let err = error as BusinessError; 143 console.error('Failed to addInput. errorCode = ' + err.code); 144 } 145 146 // 向会话中添加预览输出流 147 try { 148 captureSession.addOutput(previewOutput); 149 } catch (error) { 150 let err = error as BusinessError; 151 console.error('Failed to addOutput(previewOutput). errorCode = ' + err.code); 152 } 153 154 // 向会话中添加拍照输出流 155 try { 156 captureSession.addOutput(photoOutput); 157 } catch (error) { 158 let err = error as BusinessError; 159 console.error('Failed to addOutput(photoOutput). errorCode = ' + err.code); 160 } 161 162 // 提交会话配置 163 await captureSession.commitConfig(); 164 165 // 启动会话 166 await captureSession.start().then(() => { 167 console.info('Promise returned to indicate the session start success.'); 168 }); 169 // 判断设备是否支持闪光灯 170 let flashStatus: boolean = false; 171 try { 172 flashStatus = captureSession.hasFlash(); 173 } catch (error) { 174 let err = error as BusinessError; 175 console.error('Failed to hasFlash. errorCode = ' + err.code); 176 } 177 console.info('Promise returned with the flash light support status:' + flashStatus); 178 179 if (flashStatus) { 180 // 判断是否支持自动闪光灯模式 181 let flashModeStatus: boolean = false; 182 try { 183 let status: boolean = captureSession.isFlashModeSupported(camera.FlashMode.FLASH_MODE_AUTO); 184 flashModeStatus = status; 185 } catch (error) { 186 let err = error as BusinessError; 187 console.error('Failed to check whether the flash mode is supported. errorCode = ' + err.code); 188 } 189 if(flashModeStatus) { 190 // 设置自动闪光灯模式 191 try { 192 captureSession.setFlashMode(camera.FlashMode.FLASH_MODE_AUTO); 193 } catch (error) { 194 let err = error as BusinessError; 195 console.error('Failed to set the flash mode. errorCode = ' + err.code); 196 } 197 } 198 } 199 200 // 判断是否支持连续自动变焦模式 201 let focusModeStatus: boolean = false; 202 try { 203 let status: boolean = captureSession.isFocusModeSupported(camera.FocusMode.FOCUS_MODE_CONTINUOUS_AUTO); 204 focusModeStatus = status; 205 } catch (error) { 206 let err = error as BusinessError; 207 console.error('Failed to check whether the focus mode is supported. errorCode = ' + err.code); 208 } 209 210 if (focusModeStatus) { 211 // 设置连续自动变焦模式 212 try { 213 captureSession.setFocusMode(camera.FocusMode.FOCUS_MODE_CONTINUOUS_AUTO); 214 } catch (error) { 215 let err = error as BusinessError; 216 console.error('Failed to set the focus mode. errorCode = ' + err.code); 217 } 218 } 219 220 // 获取相机支持的可变焦距比范围 221 let zoomRatioRange: Array<number> = []; 222 try { 223 zoomRatioRange = captureSession.getZoomRatioRange(); 224 } catch (error) { 225 let err = error as BusinessError; 226 console.error('Failed to get the zoom ratio range. errorCode = ' + err.code); 227 } 228 if (zoomRatioRange.length <= 0) { 229 return; 230 } 231 // 设置可变焦距比 232 try { 233 captureSession.setZoomRatio(zoomRatioRange[0]); 234 } catch (error) { 235 let err = error as BusinessError; 236 console.error('Failed to set the zoom ratio value. errorCode = ' + err.code); 237 } 238 let photoCaptureSetting: camera.PhotoCaptureSetting = { 239 quality: camera.QualityLevel.QUALITY_LEVEL_HIGH, // 设置图片质量高 240 rotation: camera.ImageRotation.ROTATION_0 // 设置图片旋转角度0 241 } 242 // 使用当前拍照设置进行拍照 243 photoOutput.capture(photoCaptureSetting, (err: BusinessError) => { 244 if (err) { 245 console.error('Failed to capture the photo ${err.message}'); 246 return; 247 } 248 console.info('Callback invoked to indicate the photo capture request success.'); 249 }); 250 // 停止当前会话 251 captureSession.stop(); 252 253 // 释放相机输入流 254 cameraInput.close(); 255 256 // 释放预览输出流 257 previewOutput.release(); 258 259 // 释放拍照输出流 260 photoOutput.release(); 261 262 // 释放会话 263 captureSession.release(); 264 265 // 会话置空 266 captureSession = undefined; 267} 268``` 269 270