1e41f4b71Sopenharmony_ci# Deferred Photo Delivery (ArkTS)
2e41f4b71Sopenharmony_ci
3e41f4b71Sopenharmony_ciAs 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.
4e41f4b71Sopenharmony_ci- 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.
5e41f4b71Sopenharmony_ci- 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.
6e41f4b71Sopenharmony_ci
7e41f4b71Sopenharmony_ciDeferred photo delivery further reduces the response delay, delivering a better user experience.
8e41f4b71Sopenharmony_ci
9e41f4b71Sopenharmony_ciTo develop deferred photo delivery, perform the following steps:
10e41f4b71Sopenharmony_ci
11e41f4b71Sopenharmony_ci- Listen for the **photoAssetAvailable** event through **PhotoOutput** to obtain a **PhotoAsset** object of [photoAccessHelper](../../reference/apis-media-library-kit/js-apis-photoAccessHelper.md).
12e41f4b71Sopenharmony_ci- Call the mediaLibrary APIs to read or flush images to the disk through the **PhotoAsset** object.
13e41f4b71Sopenharmony_ci
14e41f4b71Sopenharmony_ci> **NOTE**
15e41f4b71Sopenharmony_ci> 
16e41f4b71Sopenharmony_ci> - 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.
17e41f4b71Sopenharmony_ci> - 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.
18e41f4b71Sopenharmony_ci
19e41f4b71Sopenharmony_ci## How to Develop
20e41f4b71Sopenharmony_ci
21e41f4b71Sopenharmony_ciRead [Camera](../../reference/apis-camera-kit/js-apis-camera.md) for the API reference.
22e41f4b71Sopenharmony_ci
23e41f4b71Sopenharmony_ci1. Import dependencies. Specifically, import the camera, image, and mediaLibrary modules.
24e41f4b71Sopenharmony_ci
25e41f4b71Sopenharmony_ci   ```ts
26e41f4b71Sopenharmony_ci   import { camera } from '@kit.CameraKit';
27e41f4b71Sopenharmony_ci   import { BusinessError } from '@kit.BasicServicesKit';
28e41f4b71Sopenharmony_ci   import { common } from '@kit.AbilityKit';
29e41f4b71Sopenharmony_ci   import { photoAccessHelper } from '@kit.MediaLibraryKit';
30e41f4b71Sopenharmony_ci   ```
31e41f4b71Sopenharmony_ci
32e41f4b71Sopenharmony_ci2. Determine the photo output stream.
33e41f4b71Sopenharmony_ci
34e41f4b71Sopenharmony_ci   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.
35e41f4b71Sopenharmony_ci
36e41f4b71Sopenharmony_ci   ```ts
37e41f4b71Sopenharmony_ci   function getPhotoOutput(cameraManager: camera.CameraManager, 
38e41f4b71Sopenharmony_ci                           cameraOutputCapability: camera.CameraOutputCapability): camera.PhotoOutput | undefined {
39e41f4b71Sopenharmony_ci     let photoProfilesArray: Array<camera.Profile> = cameraOutputCapability.photoProfiles;
40e41f4b71Sopenharmony_ci     if (!photoProfilesArray) {
41e41f4b71Sopenharmony_ci       console.error("createOutput photoProfilesArray == null || undefined");
42e41f4b71Sopenharmony_ci     }
43e41f4b71Sopenharmony_ci     let photoOutput: camera.PhotoOutput | undefined = undefined;
44e41f4b71Sopenharmony_ci     try {
45e41f4b71Sopenharmony_ci       photoOutput = cameraManager.createPhotoOutput(photoProfilesArray[0]);
46e41f4b71Sopenharmony_ci     } catch (error) {
47e41f4b71Sopenharmony_ci       let err = error as BusinessError;
48e41f4b71Sopenharmony_ci       console.error(`Failed to createPhotoOutput. error: ${JSON.stringify(err)}`);
49e41f4b71Sopenharmony_ci     }
50e41f4b71Sopenharmony_ci     return photoOutput;
51e41f4b71Sopenharmony_ci   }
52e41f4b71Sopenharmony_ci   ```
53e41f4b71Sopenharmony_ci
54e41f4b71Sopenharmony_ci3. Set the **photoAssetAvailable** callback.
55e41f4b71Sopenharmony_ci
56e41f4b71Sopenharmony_ci   > **NOTE**
57e41f4b71Sopenharmony_ci   > 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**.
58e41f4b71Sopenharmony_ci   
59e41f4b71Sopenharmony_ci   ```ts
60e41f4b71Sopenharmony_cifunction photoAssetAvailableCallback(err: BusinessError, photoAsset: photoAccessHelper.PhotoAsset): void {
61e41f4b71Sopenharmony_ci     if (err) {
62e41f4b71Sopenharmony_ci       console.error(`photoAssetAvailable error: ${JSON.stringify(err)}.`);
63e41f4b71Sopenharmony_ci       return;
64e41f4b71Sopenharmony_ci     }
65e41f4b71Sopenharmony_ci     console.info('photoOutPutCallBack photoAssetAvailable');
66e41f4b71Sopenharmony_ci     // You can call mediaLibrary APIs through photoAsset to customize image processing.
67e41f4b71Sopenharmony_ci     // 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.
68e41f4b71Sopenharmony_ci     // 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.
69e41f4b71Sopenharmony_ci   }
70e41f4b71Sopenharmony_ci   
71e41f4b71Sopenharmony_ci   function onPhotoOutputPhotoAssetAvailable(photoOutput: camera.PhotoOutput): void {
72e41f4b71Sopenharmony_ci     photoOutput.on('photoAssetAvailable', photoAssetAvailableCallback);
73e41f4b71Sopenharmony_ci   }
74e41f4b71Sopenharmony_ci   ```
75e41f4b71Sopenharmony_ci   
76e41f4b71Sopenharmony_ci   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).
77e41f4b71Sopenharmony_ci
78e41f4b71Sopenharmony_ci   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).
79e41f4b71Sopenharmony_ci
80e41f4b71Sopenharmony_ci4. 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).
81e41f4b71Sopenharmony_ci
82e41f4b71Sopenharmony_ci## Status Listening
83e41f4b71Sopenharmony_ci
84e41f4b71Sopenharmony_ciDuring 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.
85e41f4b71Sopenharmony_ci
86e41f4b71Sopenharmony_ci- 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.
87e41f4b71Sopenharmony_ci
88e41f4b71Sopenharmony_ci  ```ts
89e41f4b71Sopenharmony_ci  function onPhotoOutputCaptureStart(photoOutput: camera.PhotoOutput): void {
90e41f4b71Sopenharmony_ci    photoOutput.on('captureStartWithInfo', (err: BusinessError, captureStartInfo: camera.CaptureStartInfo) => {
91e41f4b71Sopenharmony_ci      if (err !== undefined && err.code !== 0) {
92e41f4b71Sopenharmony_ci        return;
93e41f4b71Sopenharmony_ci      }
94e41f4b71Sopenharmony_ci      console.info(`photo capture started, captureId : ${captureStartInfo.captureId}`);
95e41f4b71Sopenharmony_ci    });
96e41f4b71Sopenharmony_ci  }
97e41f4b71Sopenharmony_ci  ```
98e41f4b71Sopenharmony_ci
99e41f4b71Sopenharmony_ci- 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.
100e41f4b71Sopenharmony_ci
101e41f4b71Sopenharmony_ci  ```ts
102e41f4b71Sopenharmony_ci  function onPhotoOutputCaptureEnd(photoOutput: camera.PhotoOutput): void {
103e41f4b71Sopenharmony_ci    photoOutput.on('captureEnd', (err: BusinessError, captureEndInfo: camera.CaptureEndInfo) => {
104e41f4b71Sopenharmony_ci      if (err !== undefined && err.code !== 0) {
105e41f4b71Sopenharmony_ci        return;
106e41f4b71Sopenharmony_ci      }
107e41f4b71Sopenharmony_ci      console.info(`photo capture end, captureId : ${captureEndInfo.captureId}`);
108e41f4b71Sopenharmony_ci      console.info(`frameCount : ${captureEndInfo.frameCount}`);
109e41f4b71Sopenharmony_ci    });
110e41f4b71Sopenharmony_ci  }
111e41f4b71Sopenharmony_ci  ```
112e41f4b71Sopenharmony_ci
113e41f4b71Sopenharmony_ci- 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).
114e41f4b71Sopenharmony_ci
115e41f4b71Sopenharmony_ci  ```ts
116e41f4b71Sopenharmony_ci  function onPhotoOutputError(photoOutput: camera.PhotoOutput): void {
117e41f4b71Sopenharmony_ci    photoOutput.on('error', (error: BusinessError) => {
118e41f4b71Sopenharmony_ci      console.error(`Photo output error code: ${error.code}`);
119e41f4b71Sopenharmony_ci    });
120e41f4b71Sopenharmony_ci  }
121e41f4b71Sopenharmony_ci  ```
122