1# High-Performance Camera Photographing Sample (for System Applications Only) (ArkTS) 2 3This topic provides sample code that covers the complete high-performance photographing process to help you understand the complete API calling sequence. 4 5Before referring to the sample code, you are advised to read [High-Performance Camera Photographing (for System Applications Only) (ArkTS)](camera-deferred-photo.md), [Device Input Management](camera-device-input.md), [Camera Session Management](camera-session-management.md), and [Camera Photographing](camera-shooting.md). 6 7## Development Process 8 9After obtaining the output stream capabilities supported by the camera, create a photo stream. The development process is as follows: 10 11 12 13## Sample Code 14 15For details about how to obtain the context, see [Obtaining the Context of UIAbility](../../application-models/uiability-usage.md#obtaining-the-context-of-uiability). 16 17```ts 18import { camera } from '@kit.CameraKit'; 19import { image } from '@kit.ImageKit'; 20import { BusinessError } from '@kit.BasicServicesKit'; 21import { common } from '@kit.AbilityKit'; 22import { fileIo as fs } from '@kit.CoreFileKit'; 23import { photoAccessHelper } from '@kit.MediaLibraryKit'; 24 25let context = getContext(this); 26 27// Flush the original image in write-file mode. 28async function savePicture(photoObj: camera.Photo): Promise<void> { 29 let accessHelper = photoAccessHelper.getPhotoAccessHelper(context); 30 let testFileName = 'testFile' + Date.now() + '.jpg'; 31 // To call createAsset(), the application must have the ohos.permission.READ_IMAGEVIDEO and ohos.permission.WRITE_IMAGEVIDEO permissions. 32 let photoAsset = await accessHelper.createAsset(testFileName); 33 const fd = await photoAsset.open('rw'); 34 let buffer: ArrayBuffer | undefined = undefined; 35 photoObj.main.getComponent(image.ComponentType.JPEG, (errCode: BusinessError, component: image.Component): void => { 36 if (errCode || component === undefined) { 37 console.error('getComponent failed'); 38 return; 39 } 40 if (component.byteBuffer) { 41 buffer = component.byteBuffer; 42 } else { 43 console.error('byteBuffer is null'); 44 return; 45 } 46 }); 47 if (buffer) { 48 await fs.write(fd, buffer); 49 } 50 await photoAsset.close(fd); 51 await photoObj.release(); 52} 53 54// Flush the thumbnail by calling the mediaLibrary API. 55async function saveDeferredPhoto(proxyObj: camera.DeferredPhotoProxy): Promise<void> { 56 try { 57 // Create a photoAsset. 58 let accessHelper = photoAccessHelper.getPhotoAccessHelper(context); 59 let testFileName = 'testFile' + Date.now() + '.jpg'; 60 let photoAsset = await accessHelper.createAsset(testFileName); 61 // Pass the thumbnail proxy class object to the mediaLibrary. 62 let mediaRequest: photoAccessHelper.MediaAssetChangeRequest = new photoAccessHelper.MediaAssetChangeRequest(photoAsset); 63 mediaRequest.addResource(photoAccessHelper.ResourceType.PHOTO_PROXY, proxyObj); 64 let res = await accessHelper.applyChanges(mediaRequest); 65 console.info('saveDeferredPhoto success.'); 66 } catch (err) { 67 console.error(`Failed to saveDeferredPhoto. error: ${JSON.stringify(err)}`); 68 } 69} 70 71async function deferredPhotoCase(baseContext: common.BaseContext, surfaceId: string): Promise<void> { 72 // Create a CameraManager object. 73 let cameraManager: camera.CameraManager = camera.getCameraManager(baseContext); 74 if (!cameraManager) { 75 console.error("camera.getCameraManager error"); 76 return; 77 } 78 // Listen for camera status changes. 79 cameraManager.on('cameraStatus', (err: BusinessError, cameraStatusInfo: camera.CameraStatusInfo) => { 80 if (err !== undefined && err.code !== 0) { 81 console.error(`cameraStatus with errorCode: ${err.code}`); 82 return; 83 } 84 console.info(`camera : ${cameraStatusInfo.camera.cameraId}`); 85 console.info(`status: ${cameraStatusInfo.status}`); 86 }); 87 88 // Obtain the camera list. 89 let cameraArray: Array<camera.CameraDevice> = cameraManager.getSupportedCameras(); 90 if (cameraArray.length <= 0) { 91 console.error("cameraManager.getSupportedCameras error"); 92 return; 93 } 94 95 for (let index = 0; index < cameraArray.length; index++) { 96 console.info('cameraId : ' + cameraArray[index].cameraId); // Obtain the camera ID. 97 console.info('cameraPosition : ' + cameraArray[index].cameraPosition); // Obtain the camera position. 98 console.info('cameraType : ' + cameraArray[index].cameraType); // Obtain the camera type. 99 console.info('connectionType : ' + cameraArray[index].connectionType); // Obtain the camera connection type. 100 } 101 102 // Create a camera input stream. 103 let cameraInput: camera.CameraInput | undefined = undefined; 104 try { 105 cameraInput = cameraManager.createCameraInput(cameraArray[0]); 106 } catch (error) { 107 let err = error as BusinessError; 108 console.error('Failed to createCameraInput errorCode = ' + err.code); 109 } 110 if (cameraInput === undefined) { 111 return; 112 } 113 114 // Listen for camera input errors. 115 let cameraDevice: camera.CameraDevice = cameraArray[0]; 116 cameraInput.on('error', cameraDevice, (error: BusinessError) => { 117 console.error(`Camera input error code: ${error.code}`); 118 }) 119 120 // Open a camera. 121 await cameraInput.open(); 122 123 // Obtain the supported modes. 124 let sceneModes: Array<camera.SceneMode> = cameraManager.getSupportedSceneModes(cameraArray[0]); 125 let isSupportPhotoMode: boolean = sceneModes.indexOf(camera.SceneMode.NORMAL_PHOTO) >= 0; 126 if (!isSupportPhotoMode) { 127 console.error('photo mode not support'); 128 return; 129 } 130 // Obtain the output streams supported by the camera. 131 let cameraOutputCap: camera.CameraOutputCapability = cameraManager.getSupportedOutputCapability(cameraArray[0], camera.SceneMode.NORMAL_PHOTO); 132 if (!cameraOutputCap) { 133 console.error("cameraManager.getSupportedOutputCapability error"); 134 return; 135 } 136 console.info("outputCapability: " + JSON.stringify(cameraOutputCap)); 137 138 let previewProfilesArray: Array<camera.Profile> = cameraOutputCap.previewProfiles; 139 if (!previewProfilesArray) { 140 console.error("createOutput previewProfilesArray == null || undefined"); 141 } 142 143 let photoProfilesArray: Array<camera.Profile> = cameraOutputCap.photoProfiles; 144 if (!photoProfilesArray) { 145 console.error("createOutput photoProfilesArray == null || undefined"); 146 } 147 148 // Create a preview output stream. For details about the surfaceId parameter, see the XComponent. The preview stream uses the surface provided by the XComponent. 149 let previewOutput: camera.PreviewOutput | undefined = undefined; 150 try { 151 previewOutput = cameraManager.createPreviewOutput(previewProfilesArray[0], surfaceId); 152 } catch (error) { 153 let err = error as BusinessError; 154 console.error(`Failed to create the PreviewOutput instance. error code: ${err.code}`); 155 } 156 if (previewOutput === undefined) { 157 return; 158 } 159 // Listen for preview output errors. 160 previewOutput.on('error', (error: BusinessError) => { 161 console.error(`Preview output error code: ${error.code}`); 162 }); 163 // Create a photo output stream. 164 let photoOutput: camera.PhotoOutput | undefined = undefined; 165 try { 166 photoOutput = cameraManager.createPhotoOutput(photoProfilesArray[0]); 167 } catch (error) { 168 let err = error as BusinessError; 169 console.error('Failed to createPhotoOutput errorCode = ' + err.code); 170 } 171 if (photoOutput === undefined) { 172 return; 173 } 174 // Create a session. 175 let photoSession: camera.PhotoSession | undefined = undefined; 176 try { 177 photoSession = cameraManager.createSession(camera.SceneMode.NORMAL_PHOTO) as camera.PhotoSession; 178 } catch (error) { 179 let err = error as BusinessError; 180 console.error('Failed to create the photoSession instance. errorCode = ' + err.code); 181 } 182 if (photoSession === undefined) { 183 return; 184 } 185 // Listen for session errors. 186 photoSession.on('error', (error: BusinessError) => { 187 console.error(`Capture session error code: ${error.code}`); 188 }); 189 190 // Start configuration for the session. 191 try { 192 photoSession.beginConfig(); 193 } catch (error) { 194 let err = error as BusinessError; 195 console.error('Failed to beginConfig. errorCode = ' + err.code); 196 } 197 198 // Add the camera input stream to the session. 199 try { 200 photoSession.addInput(cameraInput); 201 } catch (error) { 202 let err = error as BusinessError; 203 console.error('Failed to addInput. errorCode = ' + err.code); 204 } 205 206 // Add the preview output stream to the session. 207 try { 208 photoSession.addOutput(previewOutput); 209 } catch (error) { 210 let err = error as BusinessError; 211 console.error('Failed to addOutput(previewOutput). errorCode = ' + err.code); 212 } 213 214 // Add the photo output stream to the session. 215 try { 216 photoSession.addOutput(photoOutput); 217 } catch (error) { 218 let err = error as BusinessError; 219 console.error('Failed to addOutput(photoOutput). errorCode = ' + err.code); 220 } 221 222 // Register a callback to listen for original images. 223 photoOutput.on('photoAvailable', (err: BusinessError, photoObj: camera.Photo): void => { 224 if (err) { 225 console.info(`photoAvailable error: ${JSON.stringify(err)}.`); 226 return; 227 } 228 savePicture(photoObj).then(() => { 229 // Release the photo object after the flushing is complete. 230 photoObj.release(); 231 }); 232 }); 233 234 // Register a callback to listen for thumbnail proxies. 235 photoOutput.on('deferredPhotoProxyAvailable', (err: BusinessError, proxyObj: camera.DeferredPhotoProxy): void => { 236 if (err) { 237 console.info(`deferredPhotoProxyAvailable error: ${JSON.stringify(err)}.`); 238 return; 239 } 240 console.info('photoOutPutCallBack deferredPhotoProxyAvailable'); 241 // Obtain the pixel map of a thumbnail. 242 proxyObj.getThumbnail().then((thumbnail: image.PixelMap) => { 243 AppStorage.setOrCreate('proxyThumbnail', thumbnail); 244 }); 245 // Call the mediaLibrary API to flush the thumbnail. 246 saveDeferredPhoto(proxyObj).then(() => { 247 // Release the thumbnail proxy class object after the flushing is complete. 248 proxyObj.release(); 249 }); 250 }); 251 252 // Check whether deferred photo delivery is supported. 253 let isSupportDeferred: boolean = photoOutput.isDeferredImageDeliverySupported(camera.DeferredDeliveryImageType.PHOTO); 254 console.info('isDeferredImageDeliverySupported res:' + isSupportDeferred); 255 if (isSupportDeferred) { 256 // Enable deferred photo delivery. 257 photoOutput.deferImageDelivery(camera.DeferredDeliveryImageType.PHOTO); 258 // Check whether deferred photo delivery is enabled. 259 let isSupportEnabled: boolean = photoOutput.isDeferredImageDeliveryEnabled(camera.DeferredDeliveryImageType.PHOTO); 260 console.info('isDeferredImageDeliveryEnabled res:' + isSupportEnabled); 261 } 262 263 // Commit the session configuration. 264 await photoSession.commitConfig(); 265 266 // Start the session. 267 await photoSession.start().then(() => { 268 console.info('Promise returned to indicate the session start success.'); 269 }); 270 // Check whether the camera has flash. 271 let flashStatus: boolean = false; 272 try { 273 flashStatus = photoSession.hasFlash(); 274 } catch (error) { 275 let err = error as BusinessError; 276 console.error('Failed to hasFlash. errorCode = ' + err.code); 277 } 278 console.info('Returned with the flash light support status:' + flashStatus); 279 280 if (flashStatus) { 281 // Check whether the auto flash mode is supported. 282 let flashModeStatus: boolean = false; 283 try { 284 let status: boolean = photoSession.isFlashModeSupported(camera.FlashMode.FLASH_MODE_AUTO); 285 flashModeStatus = status; 286 } catch (error) { 287 let err = error as BusinessError; 288 console.error('Failed to check whether the flash mode is supported. errorCode = ' + err.code); 289 } 290 if(flashModeStatus) { 291 // Set the flash mode to auto. 292 try { 293 photoSession.setFlashMode(camera.FlashMode.FLASH_MODE_AUTO); 294 } catch (error) { 295 let err = error as BusinessError; 296 console.error('Failed to set the flash mode. errorCode = ' + err.code); 297 } 298 } 299 } 300 301 // Check whether the continuous auto focus is supported. 302 let focusModeStatus: boolean = false; 303 try { 304 let status: boolean = photoSession.isFocusModeSupported(camera.FocusMode.FOCUS_MODE_CONTINUOUS_AUTO); 305 focusModeStatus = status; 306 } catch (error) { 307 let err = error as BusinessError; 308 console.error('Failed to check whether the focus mode is supported. errorCode = ' + err.code); 309 } 310 311 if (focusModeStatus) { 312 // Set the focus mode to continuous auto focus. 313 try { 314 photoSession.setFocusMode(camera.FocusMode.FOCUS_MODE_CONTINUOUS_AUTO); 315 } catch (error) { 316 let err = error as BusinessError; 317 console.error('Failed to set the focus mode. errorCode = ' + err.code); 318 } 319 } 320 321 // Obtain the zoom ratio range supported by the camera. 322 let zoomRatioRange: Array<number> = []; 323 try { 324 zoomRatioRange = photoSession.getZoomRatioRange(); 325 } catch (error) { 326 let err = error as BusinessError; 327 console.error('Failed to get the zoom ratio range. errorCode = ' + err.code); 328 } 329 if (zoomRatioRange.length <= 0) { 330 return; 331 } 332 // Set a zoom ratio. 333 try { 334 photoSession.setZoomRatio(zoomRatioRange[0]); 335 } catch (error) { 336 let err = error as BusinessError; 337 console.error('Failed to set the zoom ratio value. errorCode = ' + err.code); 338 } 339 let photoCaptureSetting: camera.PhotoCaptureSetting = { 340 quality: camera.QualityLevel.QUALITY_LEVEL_HIGH, // Set the photo quality to high. 341 rotation: camera.ImageRotation.ROTATION_0 // Set the rotation angle of the photo to 0. 342 } 343 // Use the current photographing settings to take photos. 344 photoOutput.capture(photoCaptureSetting, (err: BusinessError) => { 345 if (err) { 346 console.error(`Failed to capture the photo ${err.message}`); 347 return; 348 } 349 console.info('Callback invoked to indicate the photo capture request success.'); 350 }); 351 // Stop the session. 352 photoSession.stop(); 353 354 // Release the camera input stream. 355 cameraInput.close(); 356 357 // Release the preview output stream. 358 previewOutput.release(); 359 360 // Release the photo output stream. 361 photoOutput.release(); 362 363 // Release the session. 364 photoSession.release(); 365 366 // Set the session to null. 367 photoSession = undefined; 368} 369``` 370