1# Deferred Photo Delivery (ArkTS) 2 3As an important feature of the camera, deferred photo delivery enables the system, after receiving a photographing task from an application, to report images of different quality in multiple phases. 4- In the first phase, the system quickly reports a low-quality image. The application receives a **PhotoAsset** object through the callback. Through this object, the application can call the mediaLibrary APIs to read the image or flush the image to the disk. 5- In the second phase, the deferred photo delivery subservice performs scheduling based on the system pressure and custom scenarios, and sends the postprocessed original image to the mediaLibrary to replace the low-quality image. 6 7Deferred photo delivery further reduces the response delay, delivering a better user experience. 8 9To develop deferred photo delivery, perform the following steps: 10 11- Listen for the **photoAssetAvailable** event through **PhotoOutput** to obtain a **PhotoAsset** object of [photoAccessHelper](../../reference/apis-media-library-kit/js-apis-photoAccessHelper.md). 12- Call the mediaLibrary APIs to read or flush images to the disk through the **PhotoAsset** object. 13 14> **NOTE** 15> 16> - Deferred photo delivery varies according to the device and type. Therefore, if the device or type is changed, the deferred photo delivery capability may change. 17> - Applications do not need to proactively enable deferred photo delivery. Instead, the camera framework checks whether the device and type support deferred photo delivery during stream assignment and if so, automatically enables deferred photo delivery. 18 19## How to Develop 20 21Read [Camera](../../reference/apis-camera-kit/js-apis-camera.md) for the API reference. 22 231. Import dependencies. Specifically, import the camera, image, and mediaLibrary modules. 24 25 ```ts 26 import { camera } from '@kit.CameraKit'; 27 import { BusinessError } from '@kit.BasicServicesKit'; 28 import { common } from '@kit.AbilityKit'; 29 import { photoAccessHelper } from '@kit.MediaLibraryKit'; 30 ``` 31 322. Determine the photo output stream. 33 34 You can use the **photoProfiles** attribute of the [CameraOutputCapability](../../reference/apis-camera-kit/js-apis-camera.md#cameraoutputcapability) class to obtain the photo output streams supported by the device and use [createPhotoOutput](../../reference/apis-camera-kit/js-apis-camera.md#createphotooutput11) to create a photo output stream. 35 36 ```ts 37 function getPhotoOutput(cameraManager: camera.CameraManager, 38 cameraOutputCapability: camera.CameraOutputCapability): camera.PhotoOutput | undefined { 39 let photoProfilesArray: Array<camera.Profile> = cameraOutputCapability.photoProfiles; 40 if (!photoProfilesArray) { 41 console.error("createOutput photoProfilesArray == null || undefined"); 42 } 43 let photoOutput: camera.PhotoOutput | undefined = undefined; 44 try { 45 photoOutput = cameraManager.createPhotoOutput(photoProfilesArray[0]); 46 } catch (error) { 47 let err = error as BusinessError; 48 console.error(`Failed to createPhotoOutput. error: ${JSON.stringify(err)}`); 49 } 50 return photoOutput; 51 } 52 ``` 53 543. Set the **photoAssetAvailable** callback. 55 56 > **NOTE** 57 > If the **photoAssetAvailable** callback has been registered and the **photoAvailable** callback is registered after the session starts, the stream will be restarted. Therefore, you are not advised to register both **photoAvailable** and **photoAssetAvailable**. 58 59 ```ts 60function photoAssetAvailableCallback(err: BusinessError, photoAsset: photoAccessHelper.PhotoAsset): void { 61 if (err) { 62 console.error(`photoAssetAvailable error: ${JSON.stringify(err)}.`); 63 return; 64 } 65 console.info('photoOutPutCallBack photoAssetAvailable'); 66 // You can call mediaLibrary APIs through photoAsset to customize image processing. 67 // Processing method 1: Call the mediaLibrary flush API to save the low-quality image in the first phase. After the real image in the second phase is ready, the mediaLibrary proactively replaces the image flushed. 68 // Processing method 2: Call the mediaLibrary API to request an image and register the buffer callback to receive the low-quality or high-quality image. 69 } 70 71 function onPhotoOutputPhotoAssetAvailable(photoOutput: camera.PhotoOutput): void { 72 photoOutput.on('photoAssetAvailable', photoAssetAvailableCallback); 73 } 74 ``` 75 76 For details about the mediaLibrary API used to flush images to the disk, see [saveCameraPhoto](../../reference/apis-media-library-kit/js-apis-photoAccessHelper.md#savecameraphoto12). 77 78 For details about the mediaLibrary API used to request images, see [requestimagedata](../../reference/apis-media-library-kit/js-apis-photoAccessHelper.md#requestimagedata11) and [ondataprepare](../../reference/apis-media-library-kit/js-apis-photoAccessHelper.md#ondataprepared11). 79 804. The session configuration and photography triggering mode are the same as those in the common photographing mode. For details, see steps 4-5 in [Camera Photographing (ArkTS)](camera-shooting.md). 81 82## Status Listening 83 84During camera application development, you can listen for the status of the photo output stream, including the start of the photo stream, the start and end of the photo frame, and errors of the photo output stream. 85 86- Register the **'captureStart'** event to listen for photographing start events. This event can be registered when a **PhotoOutput** instance is created and is triggered when the bottom layer starts exposure for photographing for the first time. The capture ID is returned. 87 88 ```ts 89 function onPhotoOutputCaptureStart(photoOutput: camera.PhotoOutput): void { 90 photoOutput.on('captureStartWithInfo', (err: BusinessError, captureStartInfo: camera.CaptureStartInfo) => { 91 if (err !== undefined && err.code !== 0) { 92 return; 93 } 94 console.info(`photo capture started, captureId : ${captureStartInfo.captureId}`); 95 }); 96 } 97 ``` 98 99- Register the **'captureEnd'** event to listen for photographing end events. This event can be registered when a **PhotoOutput** instance is created and is triggered when the photographing is complete. [CaptureEndInfo](../../reference/apis-camera-kit/js-apis-camera.md#captureendinfo) is returned. 100 101 ```ts 102 function onPhotoOutputCaptureEnd(photoOutput: camera.PhotoOutput): void { 103 photoOutput.on('captureEnd', (err: BusinessError, captureEndInfo: camera.CaptureEndInfo) => { 104 if (err !== undefined && err.code !== 0) { 105 return; 106 } 107 console.info(`photo capture end, captureId : ${captureEndInfo.captureId}`); 108 console.info(`frameCount : ${captureEndInfo.frameCount}`); 109 }); 110 } 111 ``` 112 113- Register the **'error'** event to listen for photo output errors. The callback function returns an error code when an API is incorrectly used. For details about the error code types, see [CameraErrorCode](../../reference/apis-camera-kit/js-apis-camera.md#cameraerrorcode). 114 115 ```ts 116 function onPhotoOutputError(photoOutput: camera.PhotoOutput): void { 117 photoOutput.on('error', (error: BusinessError) => { 118 console.error(`Photo output error code: ${error.code}`); 119 }); 120 } 121 ``` 122