• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Accessing and Managing Moving Photos
2
3A moving photo is a photo form that combines an image and a video, empowering a static image with dynamic video effect. It helps users capture dynamic moments and improves the fault tolerance rate of photographing.
4
5The media library provides the capabilities of accessing and managing moving photo assets, including:
6
7- [Saving Moving Photo Assets](#saving-moving-photo-assets)
8- [Obtaining a Moving Photo Object](#obtaining-a-moving-photo-object)
9- [Playing Moving Photos with MovingPhotoView](movingphotoview-guidelines.md)
10- [Reading Moving Photo Assets](#reading-moving-photo-assets)
11
12Camera Kit provides the capability of taking moving photos. For details, see [Moving Photos](../camera/camera-moving-photo.md).
13
14## Saving Moving Photo Assets
15
16Use the **SaveButton** security component to save the assets (image and video) of a moving photo.
17
18With the **SaveButton** security component, the application does not need the ohos.permission.WRITE_IMAGEVIDEO permission. When the user taps the button embedded with the **SaveButton** security component, the application obtains the temporary permission to save the assets to the specified media library directory.
19
20For details, see [SaveButton](../../reference/apis-arkui/arkui-ts/ts-security-components-savebutton.md).
21
22**How to Develop**
23
241. Set the properties of the **SaveButton** security component.
252. Create a button with **SaveButton**.
263. Call [MediaAssetChangeRequest.createAssetRequest](../../reference/apis-media-library-kit/arkts-apis-photoAccessHelper-MediaAssetChangeRequest.md#createassetrequest11) to create an asset change request with **PhotoSubtype** set to **MOVING_PHOTO**.
274. Call [MediaAssetChangeRequest.addResource](../../reference/apis-media-library-kit/arkts-apis-photoAccessHelper-MediaAssetChangeRequest.md#addresource11) to set the image and video of the moving photo. The video duration of the moving photo cannot exceed 10s.
28
29   In the following example, the image and video of the moving photo are specified by **fileUri** of the [application file](../../file-management/app-file-access.md) in the application sandbox.
30
31   You can also specify the assets in **ArrayBuffer**. For details, see [MediaAssetChangeRequest.addResource(type: ResourceType, data: ArrayBuffer)](../../reference/apis-media-library-kit/arkts-apis-photoAccessHelper-MediaAssetChangeRequest.md#addresource11-1).
32
335. Call [PhotoAccessHelper.applyChanges](../../reference/apis-media-library-kit/arkts-apis-photoAccessHelper-PhotoAccessHelper.md#applychanges11) to apply changes for the moving photo.
34
35```ts
36import { photoAccessHelper } from '@kit.MediaLibraryKit';
37import { common } from '@kit.AbilityKit';
38
39@Entry
40@Component
41struct Index {
42  @State message: string = 'Hello World'
43  @State saveButtonOptions: SaveButtonOptions = {
44    icon: SaveIconStyle.FULL_FILLED,
45    text: SaveDescription.SAVE_IMAGE,
46    buttonType: ButtonType.Capsule
47  } // Set properties of SaveButton.
48
49  build() {
50    Row() {
51      Column() {
52        Text(this.message)
53          .fontSize(50)
54          .fontWeight(FontWeight.Bold)
55        SaveButton(this.saveButtonOptions) // Create a button with SaveButton.
56          .onClick(async (event, result: SaveButtonOnClickResult) => {
57             if (result == SaveButtonOnClickResult.SUCCESS) {
58               try {
59                 let context: Context = this.getUIContext().getHostContext() as common.UIAbilityContext;
60                 let phAccessHelper = photoAccessHelper.getPhotoAccessHelper(context);
61                 // Ensure that the assets specified by imageFileUri and videoFileUri exist. imageFileUri and videoFileUri specify the image and video of the moving photo to create.
62                 let imageFileUri = 'file://com.example.temptest/data/storage/el2/base/haps/entry/files/create_moving_photo.jpg';
63                 let videoFileUri = 'file://com.example.temptest/data/storage/el2/base/haps/entry/files/create_moving_photo.mp4';
64                 let assetChangeRequest: photoAccessHelper.MediaAssetChangeRequest = photoAccessHelper.MediaAssetChangeRequest.createAssetRequest(context, photoAccessHelper.PhotoType.IMAGE, "jpg", {
65                  title: "moving_photo",
66                  subtype: photoAccessHelper.PhotoSubtype.MOVING_PHOTO
67                 });
68                 assetChangeRequest.addResource(photoAccessHelper.ResourceType.IMAGE_RESOURCE, imageFileUri);
69                 assetChangeRequest.addResource(photoAccessHelper.ResourceType.VIDEO_RESOURCE, videoFileUri);
70                 await phAccessHelper.applyChanges(assetChangeRequest);
71                 console.info('create moving photo successfully, uri: ' + assetChangeRequest.getAsset().uri);
72               } catch (err) {
73                 console.error(`create moving photo failed with error: ${err.code}, ${err.message}`);
74               }
75             } else {
76               console.error('SaveButtonOnClickResult create moving photo failed');
77             }
78          })
79      }
80      .width('100%')
81    }
82    .height('100%')
83  }
84}
85```
86
87## Obtaining a Moving Photo Object
88
89- Use **Picker** to obtain a moving photo object from the media library.
90
91- Create a local moving photo object of the application by passing **fileUri** of an [application file](../../file-management/app-file-access.md) in the application sandbox.
92
93After obtaining a moving photo object, you can use [MovingPhotoView](movingphotoview-guidelines.md) to play it.
94
95### Obtaining a Moving Photo Object from the Media Library
96
971. Select the [URI of a media file](../../file-management/user-file-uri-intro.md#media-file-uri) by using **Picker**.
982. Call [PhotoAccessHelper.getAssets](../../reference/apis-media-library-kit/arkts-apis-photoAccessHelper-PhotoAccessHelper.md#getassets-1) and [FetchResult.getFirstObject](../../reference/apis-media-library-kit/arkts-apis-photoAccessHelper-FetchResult.md#getfirstobject-1) to obtain the photo asset corresponding to the URI.
993. Call [MediaAssetManager.requestMovingPhoto](../../reference/apis-media-library-kit/arkts-apis-photoAccessHelper-MediaAssetManager.md#requestmovingphoto12) to obtain the moving photo object.
100
101```ts
102import { photoAccessHelper } from '@kit.MediaLibraryKit';
103import { dataSharePredicates } from '@kit.ArkData';
104import { common } from '@kit.AbilityKit';
105
106@Entry
107@Component
108struct Index {
109  build() {
110    Row() {
111      Button("example").onClick(async () => {
112        let context: Context = this.getUIContext().getHostContext() as common.UIAbilityContext;
113        let phAccessHelper = photoAccessHelper.getPhotoAccessHelper(context);
114        example(phAccessHelper, context);
115      }).width('100%')
116    }
117    .height('90%')
118  }
119}
120
121async function example(phAccessHelper: photoAccessHelper.PhotoAccessHelper, context: Context) {
122  try {
123    // Use Picker to select the URI of the moving photo.
124    let photoSelectOptions = new photoAccessHelper.PhotoSelectOptions();
125    photoSelectOptions.MIMEType = photoAccessHelper.PhotoViewMIMETypes.MOVING_PHOTO_IMAGE_TYPE;
126    photoSelectOptions.maxSelectNumber = 9;
127    let photoViewPicker = new photoAccessHelper.PhotoViewPicker();
128    let photoSelectResult = await photoViewPicker.select(photoSelectOptions);
129    let uris = photoSelectResult.photoUris;
130    for (let i = 0; i < uris.length; i++) {
131      // Obtain the photo asset corresponding to the URI.
132      let predicates: dataSharePredicates.DataSharePredicates = new dataSharePredicates.DataSharePredicates();
133      predicates.equalTo(photoAccessHelper.PhotoKeys.URI, uris[i]);
134      let fetchOption: photoAccessHelper.FetchOptions = {
135        fetchColumns: [],
136        predicates: predicates
137      };
138      let fetchResult: photoAccessHelper.FetchResult<photoAccessHelper.PhotoAsset> = await phAccessHelper.getAssets(fetchOption);
139      let photoAsset: photoAccessHelper.PhotoAsset = await fetchResult.getFirstObject();
140      // Obtain the moving photo object corresponding to the photo asset.
141      await photoAccessHelper.MediaAssetManager.requestMovingPhoto(context, photoAsset, {
142        deliveryMode: photoAccessHelper.DeliveryMode.FAST_MODE
143      }, {
144        async onDataPrepared(movingPhoto: photoAccessHelper.MovingPhoto) {
145          if (movingPhoto !== undefined) {
146            // Customize the logic for processing the moving photo.
147            console.info('request moving photo successfully, uri: ' + movingPhoto.getUri());
148          }
149        }
150      })
151    }
152  } catch (err) {
153    console.error(`request moving photo failed with error: ${err.code}, ${err.message}`);
154  }
155}
156```
157
158### Obtaining a Moving Photo object in an Application Sandbox Directory
159
160Call [MediaAssetManager.loadMovingPhoto](../../reference/apis-media-library-kit/arkts-apis-photoAccessHelper-MediaAssetManager.md#loadmovingphoto12) to load the moving photo object in the application sandbox directory.
161
162```ts
163import { photoAccessHelper } from '@kit.MediaLibraryKit';
164import { common } from '@kit.AbilityKit';
165
166@Entry
167@Component
168struct Index {
169  @State outputText: string = 'Supported formats:\n';
170
171  build() {
172    Row() {
173      Button("example").onClick(async () => {
174        let context: Context = this.getUIContext().getHostContext() as common.UIAbilityContext;
175        example(context);
176      }).width('100%')
177    }
178    .height('90%')
179  }
180}
181
182async function example(context: Context) {
183  try {
184    let imageFileUri = 'file://com.example.temptest/data/storage/el2/base/haps/entry/files/local_moving_photo.jpg';
185    let videoFileUri = 'file://com.example.temptest/data/storage/el2/base/haps/entry/files/local_moving_photo.mp4';
186    let movingPhoto = await photoAccessHelper.MediaAssetManager.loadMovingPhoto(context, imageFileUri, videoFileUri);
187    console.info('load moving photo successfully');
188  } catch (err) {
189    console.error(`load moving photo failed with error: ${err.code}, ${err.message}`);
190  }
191}
192```
193
194## Reading Moving Photo Assets
195
196Call [MovingPhoto.requestContent](../../reference/apis-media-library-kit/arkts-apis-photoAccessHelper-MovingPhoto.md#requestcontent12) to export the image and video of a moving photo to the application sandbox directory or read the image and video data from **ArrayBuffer**.
197
198```ts
199import { photoAccessHelper } from '@kit.MediaLibraryKit';
200
201async function example(movingPhoto: photoAccessHelper.MovingPhoto) {
202  try {
203    let imageFileUri = 'file://com.example.temptest/data/storage/el2/base/haps/entry/files/request_moving_photo.jpg';
204    let videoFileUri = 'file://com.example.temptest/data/storage/el2/base/haps/entry/files/request_moving_photo.mp4';
205    await movingPhoto.requestContent(imageFileUri, videoFileUri); // Export the image and video of the moving photo to the application sandbox directory.
206    let imageData = await movingPhoto.requestContent(photoAccessHelper.ResourceType.IMAGE_RESOURCE); // Read ArrayBuffer to obtain the image data.
207    let videoData = await movingPhoto.requestContent(photoAccessHelper.ResourceType.VIDEO_RESOURCE); // Read ArrayBuffer to obtain the video data.
208  } catch (err) {
209    console.error(`request content of moving photo failed with error: ${err.code}, ${err.message}`);
210  }
211}
212```
213