• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Deferred Photo Delivery (ArkTS)
2<!--Kit: Camera Kit-->
3<!--Subsystem: Multimedia-->
4<!--Owner: @qano-->
5<!--SE: @leo_ysl-->
6<!--TSE: @xchaosioda-->
7
8As an important feature of the camera, deferred photo delivery enables the system, after receiving a photo capture task from an application, to report images of different quality levels in multiple phases.
9
10- In the first phase, the system promptly delivers an image that has undergone lightweight processing, offering a balance between reduced quality and swift image availability. The application receives a PhotoAsset object through the callback. Through this object, the application can call the media library APIs to read the image or flush the image to the disk.
11- In the second phase, the camera framework enhances the image to achieve full quality, either in response to the application's request for higher quality or when the system is not busy. The enhanced image is then sent back to the media library to replace the previously provided one.
12
13Deferred photo delivery further reduces the response delay, delivering a better user experience.
14
15To develop deferred photo delivery, perform the following steps:
16
17- Listen for the **photoAssetAvailable** event through PhotoOutput to obtain a PhotoAsset object of [photoAccessHelper](../../reference/apis-media-library-kit/arkts-apis-photoAccessHelper.md).
18- Call the media library APIs to read or flush images to the disk through the PhotoAsset object.
19
20> **NOTE**
21>
22> - 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.
23> - 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 configuration and if so, automatically enables deferred photo delivery.
24
25## How to Develop
26
27Read [Module Description](../../reference/apis-camera-kit/arkts-apis-camera.md) for the API reference.
28
291. Import dependencies. Specifically, import the camera, image, and media library modules.
30
31   ```ts
32   import { camera } from '@kit.CameraKit';
33   import { BusinessError } from '@kit.BasicServicesKit';
34   import { photoAccessHelper } from '@kit.MediaLibraryKit';
35   ```
36
372. Determine the photo output stream.
38
39   You can use the **photoProfiles** property of the [CameraOutputCapability](../../reference/apis-camera-kit/arkts-apis-camera-i.md#cameraoutputcapability) class to obtain the photo output streams supported by the device and use [createPhotoOutput](../../reference/apis-camera-kit/arkts-apis-camera-CameraManager.md#createphotooutput11) to create a photo output stream.
40
41   ```ts
42   function getPhotoOutput(cameraManager: camera.CameraManager,
43     cameraOutputCapability: camera.CameraOutputCapability): camera.PhotoOutput | undefined {
44     let photoProfilesArray: Array<camera.Profile> = cameraOutputCapability.photoProfiles;
45     if (!photoProfilesArray) {
46       console.error("createOutput photoProfilesArray == null || undefined");
47     }
48     let photoOutput: camera.PhotoOutput | undefined = undefined;
49     try {
50       photoOutput = cameraManager.createPhotoOutput(photoProfilesArray[0]);
51     } catch (error) {
52       let err = error as BusinessError;
53       console.error(`Failed to createPhotoOutput. error: ${err}`);
54     }
55     return photoOutput;
56   }
57   ```
58
593. Set the **photoAssetAvailable** callback.
60
61   > **NOTE**
62   >
63   > If the **photoAssetAvailable** callback has been registered and the **photoAvailable** callback is registered after the session starts, the stream will be restarted. In this case, only the **photoAssetAvailable** callback takes effect. Therefore, you are not advised to register both **photoAvailable** and **photoAssetAvailable**.
64
65   ```ts
66   function getPhotoAccessHelper(context: Context): photoAccessHelper.PhotoAccessHelper {
67     let phAccessHelper = photoAccessHelper.getPhotoAccessHelper(context);
68     return phAccessHelper;
69   }
70
71   function onPhotoOutputPhotoAssetAvailable(photoOutput: camera.PhotoOutput, context: Context): void {
72     photoOutput.on('photoAssetAvailable', (err: BusinessError, photoAsset: photoAccessHelper.PhotoAsset) => {
73       if (err) {
74         console.error(`photoAssetAvailable error: ${err}.`);
75         return;
76       }
77       console.info('photoOutPutCallBack photoAssetAvailable');
78       // You can call media library APIs through photoAsset to customize image processing.
79       // Processing method 1: Call the media library API to save the image in the first phase. After the image in the second phase is ready, the media library proactively replaces the image flushed.
80       mediaLibSavePhoto(photoAsset, getPhotoAccessHelper(context));
81       // Processing method 2: Call the media library API to request an image and register the buffer callback to receive the first-phase or second-phase image.
82       mediaLibRequestBuffer(photoAsset, context);
83     });
84   }
85
86   async function mediaLibSavePhoto(photoAsset: photoAccessHelper.PhotoAsset,
87     phAccessHelper: photoAccessHelper.PhotoAccessHelper): Promise<void> {
88     try {
89       let assetChangeRequest: photoAccessHelper.MediaAssetChangeRequest = new photoAccessHelper.MediaAssetChangeRequest(photoAsset);
90       assetChangeRequest.saveCameraPhoto();
91       await phAccessHelper.applyChanges(assetChangeRequest);
92       console.info('apply saveCameraPhoto successfully');
93     } catch (err) {
94       console.error(`apply saveCameraPhoto failed with error: ${err.code}, ${err.message}`);
95     }
96   }
97
98   class MediaDataHandler implements photoAccessHelper.MediaAssetDataHandler<ArrayBuffer> {
99     onDataPrepared(data: ArrayBuffer) {
100       if (data === undefined) {
101         console.error('Error occurred when preparing data');
102         return;
103       }
104       // The application can customize the processing after obtaining the image buffer.
105       console.info('on image data prepared');
106     }
107   }
108
109   async function mediaLibRequestBuffer(photoAsset: photoAccessHelper.PhotoAsset, context: Context) {
110     let requestOptions: photoAccessHelper.RequestOptions = {
111       // Configure the image return mode based on service requirements.
112       // FAST_MODE: callback for receiving the first-phase image
113       // HIGH_QUALITY_MODE: callback for receiving the second-phase image
114       // BALANCE_MODE: callback for receiving both images
115       deliveryMode: photoAccessHelper.DeliveryMode.FAST_MODE,
116     }
117     const handler = new MediaDataHandler();
118     await photoAccessHelper.MediaAssetManager.requestImageData(context, photoAsset, requestOptions, handler);
119     console.info('requestImageData successfully');
120   }
121   ```
122
123   For details about the API used to flush images, see [saveCameraPhoto](../../reference/apis-media-library-kit/arkts-apis-photoAccessHelper-MediaAssetChangeRequest.md#savecameraphoto12).
124
125   For details about the APIs used to request images, see [requestImageData](../../reference/apis-media-library-kit/arkts-apis-photoAccessHelper-MediaAssetManager.md#requestimagedata11) and [onDataPrepared](../../reference/apis-media-library-kit/arkts-apis-photoAccessHelper-MediaAssetDataHandler.md#ondataprepared11).
126
1274. The session configuration and photo capture triggering mode are the same as those in the common photo capture mode. For details, see steps 4-5 in [Photo Capture (ArkTS)](camera-shooting.md).
128
129## Status Listening
130
131During 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.
132
133- Register the **'captureStart'** event to listen for photo capture start events. This event can be registered when a PhotoOutput instance is created and is triggered when the camera device starts photo capture. The capture ID is returned.
134
135  ```ts
136  function onPhotoOutputCaptureStart(photoOutput: camera.PhotoOutput): void {
137    photoOutput.on('captureStartWithInfo', (err: BusinessError, captureStartInfo: camera.CaptureStartInfo) => {
138      if (err !== undefined && err.code !== 0) {
139        return;
140      }
141      console.info(`photo capture started, captureId : ${captureStartInfo.captureId}`);
142    });
143  }
144  ```
145
146- Register the **'captureEnd'** event to listen for photo capture end events. This event can be registered when a PhotoOutput instance is created and is triggered when the photo capture is complete. [CaptureEndInfo](../../reference/apis-camera-kit/arkts-apis-camera-i.md#captureendinfo) is returned.
147
148  ```ts
149  function onPhotoOutputCaptureEnd(photoOutput: camera.PhotoOutput): void {
150    photoOutput.on('captureEnd', (err: BusinessError, captureEndInfo: camera.CaptureEndInfo) => {
151      if (err !== undefined && err.code !== 0) {
152        return;
153      }
154      console.info(`photo capture end, captureId : ${captureEndInfo.captureId}`);
155      console.info(`frameCount : ${captureEndInfo.frameCount}`);
156    });
157  }
158  ```
159
160- Register the **'captureReady'** event to obtain the result of the next photo capture. This event can be registered when a PhotoOutput instance is created and is triggered when the camera device is ready for taking a photo. The information about the next photo capture is returned.
161
162  ```ts
163  function onPhotoOutputCaptureReady(photoOutput: camera.PhotoOutput): void {
164    photoOutput.on('captureReady', (err: BusinessError) => {
165      if (err !== undefined && err.code !== 0) {
166        return;
167      }
168      console.info(`photo capture ready`);
169    });
170  }
171  ```
172
173- 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/arkts-apis-camera-e.md#cameraerrorcode).
174
175  ```ts
176  function onPhotoOutputError(photoOutput: camera.PhotoOutput): void {
177    photoOutput.on('error', (error: BusinessError) => {
178      console.error(`Photo output error code: ${error.code}`);
179    });
180  }
181  ```
182