1# 使用人像模式拍照 2 3## 开发流程 4 5人像模式依赖于模式化管理器,在获取到模式化管理的能力后,开始创建拍照流 6 7模式化管理是对于cameraManager功能的增强与扩充,主要用于一些高级功能的管理,开发流程如下 8 9 10 11## 完整示例 12[BaseContext获取方式](../reference/apis/js-apis-inner-application-baseContext.md)。 13```ts 14import camera from '@ohos.multimedia.camera'; 15import { BusinessError } from '@ohos.base'; 16import image from '@ohos.multimedia.image'; 17import common from '@ohos.app.ability.common'; 18 19async function cameraModeCase(baseContext: common.BaseContext, surfaceId: string): Promise<void> { 20 // 创建CameraManager对象 21 let cameraManager: camera.CameraManager = camera.getCameraManager(baseContext); 22 if (!cameraManager) { 23 console.error("camera.getCameraManager error"); 24 return; 25 } 26 // 创建ModeManager对象 27 let modeManager: camera.ModeManager = camera.getModeManager(baseContext); 28 if (!cameraManager) { 29 console.error("camera.getModeManager error"); 30 return; 31 } 32 // 监听相机状态变化 33 cameraManager.on('cameraStatus', (err: BusinessError, cameraStatusInfo: camera.CameraStatusInfo) => { 34 console.info(`camera : ${cameraStatusInfo.camera.cameraId}`); 35 console.info(`status: ${cameraStatusInfo.status}`); 36 }); 37 // 获取相机列表 38 let cameraArray: Array<camera.CameraDevice> = cameraManager.getSupportedCameras(); 39 if (cameraArray.length <= 0) { 40 console.error("cameraManager.getSupportedCameras error"); 41 return; 42 } 43 44 for (let index = 0; index < cameraArray.length; index++) { 45 console.info('cameraId : ' + cameraArray[index].cameraId); // 获取相机ID 46 console.info('cameraPosition : ' + cameraArray[index].cameraPosition); // 获取相机位置 47 console.info('cameraType : ' + cameraArray[index].cameraType); // 获取相机类型 48 console.info('connectionType : ' + cameraArray[index].connectionType); // 获取相机连接类型 49 } 50 51 // 获取模式列表 52 let cameraModeArray: Array<camera.CameraMode> = modeManager.getSupportedModes(cameraArray[0]); 53 if (cameraModeArray.length <= 0) { 54 console.error("modeManager.getSupportedModes error"); 55 return; 56 } 57 // 创建相机输入流 58 let cameraInput: camera.CameraInput | undefined = undefined; 59 try { 60 cameraInput = cameraManager.createCameraInput(cameraArray[0]); 61 } catch (error) { 62 let err = error as BusinessError; 63 console.error('Failed to createCameraInput errorCode = ' + err.code); 64 } 65 // 监听cameraInput错误信息 66 let cameraDevice: camera.CameraDevice = cameraArray[0]; 67 if (cameraInput === undefined) { 68 return; 69 } 70 cameraInput.on('error', cameraDevice, (error: BusinessError) => { 71 console.info(`Camera input error code: ${error.code}`); 72 }) 73 74 // 打开相机 75 await cameraInput.open(); 76 77 // 获取当前模式相机设备支持的输出流能力 78 let cameraOutputCap: camera.CameraOutputCapability = modeManager.getSupportedOutputCapability(cameraArray[0], cameraModeArray[0]); 79 if (!cameraOutputCap) { 80 console.error("modeManager.getSupportedOutputCapability error"); 81 return; 82 } 83 console.info("outputCapability: " + JSON.stringify(cameraOutputCap)); 84 85 let previewProfilesArray: Array<camera.Profile> = cameraOutputCap.previewProfiles; 86 if (!previewProfilesArray) { 87 console.error("createOutput previewProfilesArray == null || undefined"); 88 } 89 90 let photoProfilesArray: Array<camera.Profile> = cameraOutputCap.photoProfiles; 91 if (!photoProfilesArray) { 92 console.error("createOutput photoProfilesArray == null || undefined"); 93 } 94 95 // 创建预览输出流,其中参数 surfaceId 参考上文 XComponent 组件,预览流为XComponent组件提供的surface 96 let previewOutput: camera.PreviewOutput | undefined = undefined; 97 try { 98 previewOutput = cameraManager.createPreviewOutput(previewProfilesArray[0], surfaceId); 99 } catch (error) { 100 let err = error as BusinessError; 101 console.error("Failed to create the PreviewOutput instance. error code:" + err.code); 102 } 103 if (previewOutput === undefined) { 104 return; 105 } 106 // 监听预览输出错误信息 107 previewOutput.on('error', (error: BusinessError) => { 108 console.info(`Preview output error code: ${error.code}`); 109 }) 110 // 创建ImageReceiver对象,并设置照片参数:分辨率大小是根据前面 photoProfilesArray 获取的当前设备所支持的拍照分辨率大小去设置 111 let imageReceiver: image.ImageReceiver = image.createImageReceiver(1920, 1080, 4, 8); 112 // 获取照片显示SurfaceId 113 let photoSurfaceId: string = await imageReceiver.getReceivingSurfaceId(); 114 // 创建拍照输出流 115 let photoOutput: camera.PhotoOutput | undefined = undefined; 116 try { 117 photoOutput = cameraManager.createPhotoOutput(photoProfilesArray[0], photoSurfaceId); 118 } catch (error) { 119 let err = error as BusinessError; 120 console.error('Failed to createPhotoOutput errorCode = ' + err.code); 121 } 122 if (photoOutput === undefined) { 123 return; 124 } 125 //创建portrait会话 126 let portraitSession: camera.CaptureSession | undefined = undefined; 127 try { 128 portraitSession = modeManager.createCaptureSession(cameraModeArray[0]); 129 } catch (error) { 130 let err = error as BusinessError; 131 console.error('Failed to create the CaptureSession instance. errorCode = ' + err.code); 132 } 133 if (portraitSession === undefined) { 134 return; 135 } 136 // 监听portraitSession错误信息 137 portraitSession.on('error', (error: BusinessError) => { 138 console.info(`Capture session error code: ${error.code}`); 139 }); 140 141 // 开始配置会话 142 try { 143 portraitSession.beginConfig(); 144 } catch (error) { 145 let err = error as BusinessError; 146 console.error('Failed to beginConfig. errorCode = ' + err.code); 147 } 148 149 // 向会话中添加相机输入流 150 try { 151 portraitSession.addInput(cameraInput); 152 } catch (error) { 153 let err = error as BusinessError; 154 console.error('Failed to addInput. errorCode = ' + err.code); 155 } 156 157 // 向会话中添加预览输出流 158 try { 159 portraitSession.addOutput(previewOutput); 160 } catch (error) { 161 let err = error as BusinessError; 162 console.error('Failed to addOutput(previewOutput). errorCode = ' + err.code); 163 } 164 165 // 向会话中添加拍照输出流 166 try { 167 portraitSession.addOutput(photoOutput); 168 } catch (error) { 169 let err = error as BusinessError; 170 console.error('Failed to addOutput(photoOutput). errorCode = ' + err.code); 171 } 172 173 // 提交会话配置 174 await portraitSession.commitConfig(); 175 176 // 启动会话 177 await portraitSession.start().then(() => { 178 console.info('Promise returned to indicate the session start success.'); 179 }) 180 181 // 获取支持的美颜类型 182 let beautyTypes: Array<camera.BeautyType> = []; 183 try { 184 beautyTypes = portraitSession.getSupportedBeautyTypes(); 185 } catch (error) { 186 let err = error as BusinessError; 187 console.error('Failed to get the beauty types. errorCode = ' + err.code); 188 } 189 if (beautyTypes.length <= 0) { 190 return; 191 } 192 // 获取支持的美颜类型对应的美颜强度范围 193 let beautyRanges: Array<number> = []; 194 try { 195 beautyRanges = portraitSession.getSupportedBeautyRange(beautyTypes[0]); 196 } catch (error) { 197 let err = error as BusinessError; 198 console.error('Failed to get the beauty types ranges. errorCode = ' + err.code); 199 } 200 if (beautyRanges.length <= 0) { 201 return; 202 } 203 // 设置美颜类型及对应的美颜强度 204 try { 205 portraitSession.setBeauty(beautyTypes[0], beautyRanges[0]); 206 } catch (error) { 207 let err = error as BusinessError; 208 console.error('Failed to set the beauty type value. errorCode = ' + err.code); 209 } 210 // 获取已经设置的美颜类型对应的美颜强度 211 let beautyLevel: number = -1; 212 try { 213 beautyLevel = portraitSession.getBeauty(beautyTypes[0]); 214 } catch (error) { 215 let err = error as BusinessError; 216 console.error('Failed to get the beauty type value. errorCode = ' + err.code); 217 } 218 219 if (beautyLevel === -1) { 220 return; 221 } 222 // 获取支持的滤镜类型 223 let filterTypes: Array<camera.FilterType> = []; 224 try { 225 filterTypes = portraitSession.getSupportedFilters(); 226 } catch (error) { 227 let err = error as BusinessError; 228 console.error('Failed to get the filter types. errorCode = ' + err.code); 229 } 230 if (filterTypes.length <= 0) { 231 return; 232 } 233 // 设置滤镜类型 234 try { 235 portraitSession.setFilter(filterTypes[0]); 236 } catch (error) { 237 let err = error as BusinessError; 238 console.error('Failed to set the filter type value. errorCode = ' + err.code); 239 } 240 // 获取已经设置的滤镜类型 241 let filter: number = -1; 242 try { 243 filter = portraitSession.getFilter(); 244 } catch (error) { 245 let err = error as BusinessError; 246 console.error('Failed to get the filter type value. errorCode = ' + err.code); 247 } 248 if (filter === -1) { 249 return; 250 } 251 252 // 获取支持的虚化类型 253 let portraitTypes: Array<camera.PortraitEffect> = []; 254 try { 255 let portraitSession1: camera.PortraitSession = portraitSession as camera.PortraitSession; 256 portraitTypes = portraitSession1.getSupportedPortraitEffects(); 257 } catch (error) { 258 let err = error as BusinessError; 259 console.error('Failed to get the portrait effects types. errorCode = ' + err.code); 260 } 261 if (portraitTypes.length <= 0) { 262 return; 263 } 264 // 设置虚化类型 265 try { 266 let portraitSession1: camera.PortraitSession = portraitSession as camera.PortraitSession; 267 portraitSession1.setPortraitEffect(portraitTypes[0]); 268 } catch (error) { 269 let err = error as BusinessError; 270 console.error('Failed to set the portrait effects value. errorCode = ' + err.code); 271 } 272 // 获取已经设置的虚化类型 273 let effect: camera.PortraitEffect | undefined = undefined; 274 try { 275 let portraitSession1: camera.PortraitSession = portraitSession as camera.PortraitSession; 276 effect = portraitSession1.getPortraitEffect(); 277 } catch (error) { 278 let err = error as BusinessError; 279 console.error('Failed to get the portrait effects value. errorCode = ' + err.code); 280 } 281 282 let captureSettings: camera.PhotoCaptureSetting = { 283 quality: camera.QualityLevel.QUALITY_LEVEL_HIGH, 284 rotation: camera.ImageRotation.ROTATION_0, 285 mirror: false 286 }; 287 // 使用当前拍照设置进行拍照 288 photoOutput.capture(captureSettings, async (err: BusinessError) => { 289 if (err) { 290 console.error('Failed to capture the photo ${err.message}'); 291 return; 292 } 293 console.info('Callback invoked to indicate the photo capture request success.'); 294 }); 295 // 停止当前会话 296 portraitSession.stop(); 297 298 // 释放相机输入流 299 cameraInput.close(); 300 301 // 释放预览输出流 302 previewOutput.release(); 303 304 // 释放拍照输出流 305 photoOutput.release(); 306 307 // 释放会话 308 portraitSession.release(); 309 310 // 会话置空 311 portraitSession = undefined; 312} 313``` 314