目录

Deferred Photo Delivery (ArkTS)

As 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.

Deferred photo delivery further reduces the response delay, delivering a better user experience.

To develop deferred photo delivery, perform the following steps:

  • 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.
  • 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.

How to Develop

For detailed API descriptions, see @ohos.multimedia.camera (Camera Management).

  1. Import dependencies. Specifically, import the camera, image, and media library modules.

    import { camera } from '@kit.CameraKit';
    import { BusinessError } from '@kit.BasicServicesKit';
    import { photoAccessHelper } from '@kit.MediaLibraryKit';
  2. Determine the photo output stream.

    You can use the photoProfiles property of CameraOutputCapability to obtain the photo output streams supported by the device and use createPhotoOutput to create a photo output stream.

    function getPhotoOutput(cameraManager: camera.CameraManager,
      cameraOutputCapability: camera.CameraOutputCapability): camera.PhotoOutput | undefined {
      let photoProfilesArray: Array<camera.Profile> = cameraOutputCapability.photoProfiles;
      if (photoProfilesArray===null || photoProfilesArray===undefined) {
        console.error("createOutput photoProfilesArray is null!");
        return undefined;
      }
      let photoOutput: camera.PhotoOutput | undefined = undefined;
      try {
       if (photoProfilesArray.length > 0) {
           photoOutput = cameraManager.createPhotoOutput(photoProfilesArray[0]);
       } else {
           console.error("the length of photoProfilesArray<=0!");
           return undefined;
       }
      } catch (error) {
        let err = error as BusinessError;
        console.error(`Failed to createPhotoOutput. error: ${err}`);
      }
      return photoOutput;
    }
  3. Set the photoAssetAvailable callback.

    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.

    You are not advised to register both photoAvailable and photoAssetAvailable.

    function getPhotoAccessHelper(context: Context): photoAccessHelper.PhotoAccessHelper {
      let phAccessHelper = photoAccessHelper.getPhotoAccessHelper(context);
      return phAccessHelper;
    }
    
    function onPhotoOutputPhotoAssetAvailable(photoOutput: camera.PhotoOutput, context: Context): void {
      photoOutput.on('photoAssetAvailable', (err: BusinessError, photoAsset: photoAccessHelper.PhotoAsset) => {
        if (err) {
          console.error(`photoAssetAvailable error: ${err}.`);
          return;
        }
        console.info('photoOutPutCallBack photoAssetAvailable');
        // You can call media library APIs through photoAsset to customize image processing.
        // 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.
        mediaLibSavePhoto(photoAsset, getPhotoAccessHelper(context));
        // 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.
        mediaLibRequestBuffer(photoAsset, context);
      });
    }
    
    async function mediaLibSavePhoto(photoAsset: photoAccessHelper.PhotoAsset,
      phAccessHelper: photoAccessHelper.PhotoAccessHelper): Promise<void> {
      try {
        let assetChangeRequest: photoAccessHelper.MediaAssetChangeRequest = new photoAccessHelper.MediaAssetChangeRequest(photoAsset);
        assetChangeRequest.saveCameraPhoto();
        await phAccessHelper.applyChanges(assetChangeRequest);
        console.info('apply saveCameraPhoto successfully');
      } catch (err) {
        console.error(`apply saveCameraPhoto failed with error: ${err.code}, ${err.message}`);
      }
    }
    
    class MediaDataHandler implements photoAccessHelper.MediaAssetDataHandler<ArrayBuffer> {
      onDataPrepared(data: ArrayBuffer) {
        if (data === undefined) {
          console.error('Error occurred when preparing data');
          return;
        }
        // The application can customize the processing after obtaining the image buffer.
        console.info('on image data prepared');
      }
    }
    
    async function mediaLibRequestBuffer(photoAsset: photoAccessHelper.PhotoAsset, context: Context) {
      let requestOptions: photoAccessHelper.RequestOptions = {
        // Configure the image return mode based on service requirements.
        // FAST_MODE: callback for receiving the first-phase image
        // HIGH_QUALITY_MODE: callback for receiving the second-phase image
        // BALANCE_MODE: callback for receiving both images
        deliveryMode: photoAccessHelper.DeliveryMode.FAST_MODE,
      }
      const handler = new MediaDataHandler();
      await photoAccessHelper.MediaAssetManager.requestImageData(context, photoAsset, requestOptions, handler);
      console.info('requestImageData successfully');
    }

    For details about the API used to flush images, see saveCameraPhoto.

    For details about the APIs used to request images, see requestImageData and onDataPrepared.

  4. 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).

Status Listening

During 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.