• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# 媒体资源使用指导
2
3应用可以通过photoAccessHelper的接口,对媒体资源(图片、视频)进行相关操作。
4
5> **说明:**
6>
7> - 在进行功能开发前,请开发者查阅[开发准备](photoAccessHelper-preparation.md),了解如何获取相册管理模块实例和如何申请相册管理模块功能开发相关权限。
8> - 文档中使用到photoAccessHelper的地方默认为使用开发准备中获取的对象,如未添加此段代码报photoAccessHelper未定义的错误请自行添加。
9
10为了保证应用的运行效率,大部分photoAccessHelper的接口调用都是异步的。以下异步调用的API示例均采用Promise函数,更多方式可以查阅[API参考](../../reference/apis-media-library-kit/js-apis-photoAccessHelper.md)。
11
12## 获取指定媒体资源
13
14开发者可以根据特定的条件查询媒体资源,如指定类型、指定日期、指定相册等。
15
16应用通过调用[PhotoAccessHelper.getAssets](../../reference/apis-media-library-kit/js-apis-photoAccessHelper.md#getassets-1)获取媒体资源,并传入[FetchOptions](../../reference/apis-media-library-kit/js-apis-photoAccessHelper.md#fetchoptions)对象指定检索条件。如无特别说明,文档中涉及的待获取的资源均视为已经预置且在数据库中存在相应数据。如出现按照示例代码执行出现获取资源为空的情况请确认文件是否已预置,数据库中是否存在该文件的数据。
17
18如果只想获取某个位置的对象(如第一个、最后一个、指定索引等),可以通过[FetchResult](../../reference/apis-media-library-kit/js-apis-photoAccessHelper.md#fetchresult)中的接口获取对应位置的媒体资源对象。
19
20**前提条件**
21
22- 获取相册管理模块photoAccessHelper实例。
23- 申请相册管理模块读权限'ohos.permission.READ_IMAGEVIDEO'。
24- 导入[dataSharePredicates](../../reference/apis-arkdata/js-apis-data-dataSharePredicates.md)模块。
25
26### 指定媒体文件名获取图片或视频资源
27
28下面以查询文件名为'test.jpg'的图片资源为例。
29
30```ts
31import dataSharePredicates from '@ohos.data.dataSharePredicates';
32import photoAccessHelper from '@ohos.file.photoAccessHelper';
33const context = getContext(this);
34let phAccessHelper = photoAccessHelper.getPhotoAccessHelper(context);
35
36async function example() {
37  let predicates: dataSharePredicates.DataSharePredicates = new dataSharePredicates.DataSharePredicates();
38  predicates.equalTo(photoAccessHelper.PhotoKeys.DISPLAY_NAME, 'test.jpg');
39  let fetchOptions: photoAccessHelper.FetchOptions = {
40    fetchColumns: [],
41    predicates: predicates
42  };
43  try {
44    let fetchResult: photoAccessHelper.FetchResult<photoAccessHelper.PhotoAsset> = await phAccessHelper.getAssets(fetchOptions);
45    let photoAsset: photoAccessHelper.PhotoAsset = await fetchResult.getFirstObject();
46    console.info('getAssets photoAsset.displayName : ' + photoAsset.displayName);
47    fetchResult.close();
48  } catch (err) {
49    console.error('getAssets failed with err: ' + err);
50  }
51}
52```
53
54### 指定URI获取图片或视频资源
55
56下面以查询指定URI为'file://media/Photo/1/IMG_datetime_0001/displayName.jpg'为例。
57
58```ts
59import dataSharePredicates from '@ohos.data.dataSharePredicates';
60import photoAccessHelper from '@ohos.file.photoAccessHelper';
61const context = getContext(this);
62let phAccessHelper = photoAccessHelper.getPhotoAccessHelper(context);
63
64async function example() {
65  let predicates: dataSharePredicates.DataSharePredicates = new dataSharePredicates.DataSharePredicates();
66  let uri = 'file://media/Photo/1/IMG_datetime_0001/displayName.jpg' // 需保证此uri已存在。
67  predicates.equalTo(photoAccessHelper.PhotoKeys.URI, uri.toString());
68  let fetchOptions: photoAccessHelper.FetchOptions = {
69    fetchColumns: [],
70    predicates: predicates
71  };
72
73  try {
74    let fetchResult: photoAccessHelper.FetchResult<photoAccessHelper.PhotoAsset> = await phAccessHelper.getAssets(fetchOptions);
75    let photoAsset: photoAccessHelper.PhotoAsset = await fetchResult.getFirstObject();
76    console.info('getAssets photoAsset.uri : ' + photoAsset.uri);
77    fetchResult.close();
78  } catch (err) {
79    console.error('getAssets failed with err: ' + err);
80  }
81}
82```
83
84### 指定文件添加的时间获取图片或视频资源
85
86下面以查询指定添加时间为'2022-06-01'至'2023-06-01'这一年内为例。
87
88```ts
89import dataSharePredicates from '@ohos.data.dataSharePredicates';
90import photoAccessHelper from '@ohos.file.photoAccessHelper';
91const context = getContext(this);
92let phAccessHelper = photoAccessHelper.getPhotoAccessHelper(context);
93
94async function example() {
95  let predicates: dataSharePredicates.DataSharePredicates = new dataSharePredicates.DataSharePredicates();
96  let startTime = Date.parse(new Date('2022-06-01').toString()) / 1000; // 查询起始时间距1970年1月1日的秒数值。
97  let endTime = Date.parse(new Date('2023-06-01').toString()) / 1000;  // 查询结束时间距1970年1月1日的秒数值。
98  let date_added: photoAccessHelper.PhotoKeys = photoAccessHelper.PhotoKeys.DATE_ADDED;
99  predicates.between(date_added, startTime, endTime);
100  predicates.orderByDesc(date_added); // 查询结果按照降序排序。
101  let fetchOptions: photoAccessHelper.FetchOptions = {
102    fetchColumns: [date_added], // date_added属性不属于默认查询列,需要自行添加。
103    predicates: predicates
104  };
105  try {
106    let fetchResult: photoAccessHelper.FetchResult<photoAccessHelper.PhotoAsset> = await phAccessHelper.getAssets(fetchOptions);
107    console.info('getAssets count: ' + fetchResult.getCount());
108    let photoAsset: photoAccessHelper.PhotoAsset = await fetchResult.getFirstObject();
109    console.info('getAssets photoAsset.displayName : ' + photoAsset.displayName);
110    fetchResult.close();
111  } catch (err) {
112    console.error('getAssets failed with err: ' + err);
113  }
114}
115```
116
117## 获取图片和视频缩略图
118
119通过接口[PhotoAsset.getThumbnail](../../reference/apis-media-library-kit/js-apis-photoAccessHelper.md#getthumbnail-2),传入缩略图尺寸,可以获取图片和视频缩略图。缩略图常用于UI界面展示。
120
121**前提条件**
122
123- 获取相册管理模块photoAccessHelper实例。
124- 申请相册管理模块读权限'ohos.permission.READ_IMAGEVIDEO'。
125- 导入[dataSharePredicates](../../reference/apis-arkdata/js-apis-data-dataSharePredicates.md)模块。
126
127### 获取某张图片的缩略图
128
129当需要在相册展示图片和视频、编辑预览,应用需要获取某张图片的缩略图。
130
131参考以下示例,获取图片的文件描述符fd后,需要解码为统一的PixelMap,方便在应用中进行图片显示或图片处理,具体请参考[图片解码](../image/image-decoding.md)。
132
133下面以获取一张图片的缩略图为例,缩略图尺寸为720*720。
134
135**开发步骤**
136
1371. 建立检索条件,用于获取图片资源。
1382. 调用[PhotoAccessHelper.getAssets](../../reference/apis-media-library-kit/js-apis-photoAccessHelper.md#getassets-1)接口获取图片资源。
1393. 调用[FetchResult.getFirstObject](../../reference/apis-media-library-kit/js-apis-photoAccessHelper.md#getfirstobject-1)接口获取第一张图片。
1404. 调用PhotoAsset.getThumbnail获取图片的缩略图的[PixelMap](../../reference/apis-image-kit/js-apis-image.md#pixelmap7)。
141
142```ts
143import dataSharePredicates from '@ohos.data.dataSharePredicates';
144import image from '@ohos.multimedia.image';
145import photoAccessHelper from '@ohos.file.photoAccessHelper';
146const context = getContext(this);
147let phAccessHelper = photoAccessHelper.getPhotoAccessHelper(context);
148
149async function example() {
150  let predicates: dataSharePredicates.DataSharePredicates = new dataSharePredicates.DataSharePredicates();
151  let fetchOptions: photoAccessHelper.FetchOptions = {
152    fetchColumns: [],
153    predicates: predicates
154  };
155
156  try {
157    let fetchResult: photoAccessHelper.FetchResult<photoAccessHelper.PhotoAsset> = await phAccessHelper.getAssets(fetchOptions);
158    let photoAsset: photoAccessHelper.PhotoAsset = await fetchResult.getFirstObject();
159    console.info('getAssets photoAsset.displayName : ' + photoAsset.displayName);
160    let size: image.Size = { width: 720, height: 720 };
161    let pixelMap: image.PixelMap =  await photoAsset.getThumbnail(size);
162    let imageInfo: image.ImageInfo = await pixelMap.getImageInfo()
163    console.info('getThumbnail successful, pixelMap ImageInfo size: ' + JSON.stringify(imageInfo.size));
164    fetchResult.close();
165  } catch (err) {
166    console.error('getThumbnail failed with err: ' + err);
167  }
168}
169```
170
171## 创建媒体资源
172
173创建[MediaAssetChangeRequest](../../reference/apis-media-library-kit/js-apis-photoAccessHelper.md#mediaassetchangerequest11)媒体资产变更对象并写入媒体资源内容,然后调用[PhotoAccessHelper.applyChanges](../../reference/apis-media-library-kit/js-apis-photoAccessHelper.md#applychanges11)接口提交创建资产的变更请求。
174
175**前提条件**
176
177- 获取相册管理模块photoAccessHelper实例。
178- 申请相册管理模块权限'ohos.permission.WRITE_IMAGEVIDEO'。
179
180### 创建图片或视频资源(仅向系统应用开放)
181
182下面以创建一张图片资源为例。
183
184**开发步骤**
185
1861. 定义文件名和创建选项,用于创建图片资源时设置属性。
1872. 调用MediaAssetChangeRequest.createAssetRequest接口创建资产变更请求。
1883. 调用MediaAssetChangeRequest.getWriteCacheHandler接口获取临时文件写句柄,并写入图片资源的内容。
1894. 调用PhotoAccessHelper.applyChanges接口提交资产变更请求。
190
191```ts
192import photoAccessHelper from '@ohos.file.photoAccessHelper';
193import fs from '@ohos.file.fs';
194let context = getContext(this);
195let phAccessHelper = photoAccessHelper.getPhotoAccessHelper(context);
196
197async function example() {
198  try {
199    let displayName: string = 'testPhoto' + Date.now() + '.jpg';
200    let createOption: photoAccessHelper.PhotoCreateOptions = {
201      subtype: photoAccessHelper.PhotoSubtype.DEFAULT
202    };
203    let assetChangeRequest: photoAccessHelper.MediaAssetChangeRequest = photoAccessHelper.MediaAssetChangeRequest.createAssetRequest(context, displayName, createOption);
204    let fd: number = await assetChangeRequest.getWriteCacheHandler();
205    // write date into fd
206    await fs.close(fd);
207    await phAccessHelper.applyChanges(assetChangeRequest);
208  } catch (err) {
209    console.error(`create asset failed with error: ${err.code}, ${err.message}`);
210  }
211}
212```
213
214应用还可以调用MediaAssetChangeRequest.addResource接口指定媒体资源内容的数据来源,具体包括[应用沙箱](../../reference/apis-media-library-kit/js-apis-photoAccessHelper.md#addresource11),[ArrayBuffer](../../reference/apis-media-library-kit/js-apis-photoAccessHelper.md#addresource11-1)和[PhotoProxy](../../reference/apis-media-library-kit/js-apis-photoAccessHelper-sys.md#addresource11)。
215
216## 使用安全控件创建媒体资源
217
218下面以使用安全控件创建一张图片资源为例。使用安全控件创建媒体资源无需在应用中申请相册管理模块权限'ohos.permission.WRITE_IMAGEVIDEO',详情请参考[安全控件的保存控件](../../reference/apis-arkui/arkui-ts/ts-security-components-savebutton.md)。
219
220**开发步骤**
221
2221. 设置安全控件按钮属性。
2232. 创建安全控件按钮。
2243. 调用[MediaAssetChangeRequest.createImageAssetRequest](../../reference/apis-media-library-kit/js-apis-photoAccessHelper.md#createimageassetrequest11)和[PhotoAccessHelper.applyChanges](../../reference/apis-media-library-kit/js-apis-photoAccessHelper.md#applychanges11)接口创建图片资源。
225
226```ts
227import photoAccessHelper from '@ohos.file.photoAccessHelper'
228
229@Entry
230@Component
231struct Index {
232  @State message: string = 'Hello World'
233  @State saveButtonOptions: SaveButtonOptions = {
234    icon: SaveIconStyle.FULL_FILLED,
235    text: SaveDescription.SAVE_IMAGE,
236    buttonType: ButtonType.Capsule
237  } // 设置安全控件按钮属性
238
239  build() {
240    Row() {
241      Column() {
242        Text(this.message)
243          .fontSize(50)
244          .fontWeight(FontWeight.Bold)
245        SaveButton(this.saveButtonOptions) // 创建安全控件按钮
246          .onClick(async (event, result: SaveButtonOnClickResult) => {
247             if (result == SaveButtonOnClickResult.SUCCESS) {
248               try {
249                 let context = getContext();
250                 let phAccessHelper = photoAccessHelper.getPhotoAccessHelper(context);
251                 // 需要确保fileUri对应的资源存在
252                 let fileUri = 'file://com.example.temptest/data/storage/el2/base/haps/entry/files/test.jpg';
253                 let assetChangeRequest: photoAccessHelper.MediaAssetChangeRequest = photoAccessHelper.MediaAssetChangeRequest.createImageAssetRequest(context, fileUri);
254                 await phAccessHelper.applyChanges(assetChangeRequest);
255                 console.info('createAsset successfully, uri: ' + assetChangeRequest.getAsset().uri);
256               } catch (err) {
257                 console.error(`create asset failed with error: ${err.code}, ${err.message}`);
258               }
259             } else {
260               console.error('SaveButtonOnClickResult create asset failed');
261             }
262          })
263      }
264      .width('100%')
265    }
266    .height('100%')
267  }
268}
269```
270
271## 重命名媒体资源
272
273重命名修改的是文件的PhotoAsset.displayName属性,即文件的显示文件名,包含文件后缀。
274
275调用[MediaAssetChangeRequest.setTitle](../../reference/apis-media-library-kit/js-apis-photoAccessHelper.md#settitle11)重命名后再通过[PhotoAccessHelper.applyChanges](../../reference/apis-media-library-kit/js-apis-photoAccessHelper.md#applychanges11)更新到数据库中完成修改。
276
277在重命名文件之前,需要先获取文件对象,可以通过[FetchResult](../../reference/apis-media-library-kit/js-apis-photoAccessHelper.md#fetchresult)中的接口获取对应位置的文件。
278
279**前提条件**
280
281- 获取相册管理模块photoAccessHelper实例。
282- 申请相册管理模块权限'ohos.permission.WRITE_IMAGEVIDEO'和'ohos.permission.READ_IMAGEVIDEO'。
283
284下面以将获取的图片资源中第一个文件重命名为例。
285
286**开发步骤**
287
2881. 建立检索条件,用于获取图片资源。
2892. 调用[PhotoAccessHelper.getAssets](../../reference/apis-media-library-kit/js-apis-photoAccessHelper.md#getassets-1)接口获取目标图片资源。
2903. 调用[FetchResult.getFirstObject](../../reference/apis-media-library-kit/js-apis-photoAccessHelper.md#getfirstobject-1)接口获取第一张图片,即要重命名的图片对象。
2914. 调用[MediaAssetChangeRequest.setTitle](../../reference/apis-media-library-kit/js-apis-photoAccessHelper.md#settitle11)接口将图片重命名为新的名字。
2925. 调用[PhotoAccessHelper.applyChanges](../../reference/apis-media-library-kit/js-apis-photoAccessHelper.md#applychanges11)接口将修改的图片属性更新到数据库中完成修改。
293
294```ts
295import dataSharePredicates from '@ohos.data.dataSharePredicates';
296import photoAccessHelper from '@ohos.file.photoAccessHelper';
297let context = getContext(this);
298let phAccessHelper = photoAccessHelper.getPhotoAccessHelper(context);
299
300async function example() {
301  let predicates: dataSharePredicates.DataSharePredicates = new dataSharePredicates.DataSharePredicates();
302  let fetchOptions: photoAccessHelper.FetchOptions = {
303    fetchColumns: ['title'],
304    predicates: predicates
305  };
306  let newTitle: string = 'newTestPhoto';
307
308  try {
309    let fetchResult: photoAccessHelper.FetchResult<photoAccessHelper.PhotoAsset> = await phAccessHelper.getAssets(fetchOptions);
310    let photoAsset: photoAccessHelper.PhotoAsset = await fetchResult.getFirstObject();
311    let assetChangeRequest: photoAccessHelper.MediaAssetChangeRequest = new photoAccessHelper.MediaAssetChangeRequest(photoAsset);
312    assetChangeRequest.setTitle(newTitle);
313    await phAccessHelper.applyChanges(assetChangeRequest);
314    fetchResult.close();
315  } catch (err) {
316    console.error(`rename failed with error: ${err.code}, ${err.message}`);
317  }
318}
319```
320
321## 将文件放入回收站
322
323通过[MediaAssetChangeRequest.deleteAssets](../../reference/apis-media-library-kit/js-apis-photoAccessHelper.md#deleteassets11)可以将文件放入回收站。
324
325放入回收站的文件将会保存30天,30天后会自动彻底删除。在此期间,应用用户可以通过系统应用“文件管理”或“图库”恢复文件。
326
327**前提条件**
328
329- 获取相册管理模块photoAccessHelper实例。
330- 申请相册管理模块权限'ohos.permission.WRITE_IMAGEVIDEO'和'ohos.permission.READ_IMAGEVIDEO'。
331
332下面以将文件检索结果中第一个文件放入回收站为例。
333
334**开发步骤**
335
3361. 建立检索条件,用于获取图片资源。
3372. 调用[PhotoAccessHelper.getAssets](../../reference/apis-media-library-kit/js-apis-photoAccessHelper.md#getassets-1)接口获取目标图片资源。
3383. 调用[FetchResult.getFirstObject](../../reference/apis-media-library-kit/js-apis-photoAccessHelper.md#getfirstobject-1)接口获取第一张图片,即要放入回收站的图片对象。
3394. 调用[MediaAssetChangeRequest.deleteAssets](../../reference/apis-media-library-kit/js-apis-photoAccessHelper.md#deleteassets11)接口将文件放入回收站。
340
341```ts
342import dataSharePredicates from '@ohos.data.dataSharePredicates';
343import photoAccessHelper from '@ohos.file.photoAccessHelper';
344let context = getContext(this);
345let phAccessHelper = photoAccessHelper.getPhotoAccessHelper(context);
346
347async function example() {
348  let predicates: dataSharePredicates.DataSharePredicates = new dataSharePredicates.DataSharePredicates();
349  let fetchOptions: photoAccessHelper.FetchOptions = {
350    fetchColumns: [],
351    predicates: predicates
352  };
353
354  try {
355    let fetchResult: photoAccessHelper.FetchResult<photoAccessHelper.PhotoAsset> = await phAccessHelper.getAssets(fetchOptions);
356    let photoAsset: photoAccessHelper.PhotoAsset = await fetchResult.getFirstObject();
357    await photoAccessHelper.MediaAssetChangeRequest.deleteAssets(context, [photoAsset]);
358    fetchResult.close();
359  } catch (err) {
360    console.error(`deleteAssets failed with error: ${err.code}, ${err.message}`);
361  }
362}
363```
364
365## 使用Picker选择媒体库资源
366
367用户有时需要分享图片、视频等用户文件,开发者可以通过特定接口拉起系统图库,用户自行选择待分享的资源,然后最终分享出去。此接口本身无需申请权限,目前适用于界面UIAbility,使用窗口组件触发。具体使用方式如下:
368
3691. 导入选择器模块和文件管理模块。
370
371   ```ts
372   import photoAccessHelper from '@ohos.file.photoAccessHelper';
373   import fs from '@ohos.file.fs';
374   import { BusinessError } from '@ohos.base';
375   ```
376
3772. 创建图片-音频类型文件选择选项实例。
378
379   ```ts
380   const photoSelectOptions = new photoAccessHelper.PhotoSelectOptions();
381   ```
382
3833. 选择媒体文件类型和选择媒体文件的最大数目。
384   以下示例以图片选择为例,媒体文件类型请参见[PhotoViewMIMETypes](../../reference/apis-media-library-kit/js-apis-photoAccessHelper.md#photoviewmimetypes)。
385
386   ```ts
387   photoSelectOptions.MIMEType = photoAccessHelper.PhotoViewMIMETypes.IMAGE_TYPE; // 过滤选择媒体文件类型为IMAGE
388   photoSelectOptions.maxSelectNumber = 5; // 选择媒体文件的最大数目
389   ```
390
3914. 创建图库选择器实例,调用[PhotoViewPicker.select](../../reference/apis-media-library-kit/js-apis-photoAccessHelper.md#select)接口拉起图库界面进行文件选择。文件选择成功后,返回[PhotoSelectResult](../../reference/apis-media-library-kit/js-apis-photoAccessHelper.md#photoselectresult)结果集。
392
393   select返回的uri权限是只读权限,可以根据结果集中uri进行读取文件数据操作。注意不能在picker的回调里直接使用此uri进行打开文件操作,需要定义一个全局变量保存uri,使用类似一个按钮去触发打开文件。
394
395   如有获取元数据需求,可以通过[文件管理接口](../../reference/apis-core-file-kit/js-apis-file-fs.md)和[文件URI](../../reference/apis-core-file-kit/js-apis-file-fileuri.md)根据uri获取部分文件属性信息,比如文件大小、访问时间、修改时间、文件名、文件路径等。
396
397   ```ts
398   let uris: Array<string> = [];
399   const photoViewPicker = new photoAccessHelper.PhotoViewPicker();
400   photoViewPicker.select(photoSelectOptions).then((photoSelectResult: photoAccessHelper.PhotoSelectResult) => {
401     uris = photoSelectResult.photoUris;
402     console.info('photoViewPicker.select to file succeed and uris are:' + uris);
403   }).catch((err: BusinessError) => {
404     console.error(`Invoke photoViewPicker.select failed, code is ${err.code}, message is ${err.message}`);
405   })
406   ```
407
4085. 待界面从图库返回后,再通过类似一个按钮调用其他函数,使用[fs.openSync](../../reference/apis-core-file-kit/js-apis-file-fs.md#fsopensync)接口,通过uri打开这个文件得到fd。这里需要注意接口权限参数是fs.OpenMode.READ_ONLY409
410   ```ts
411   let uri: string = '';
412   let file = fs.openSync(uri, fs.OpenMode.READ_ONLY);
413   console.info('file fd: ' + file.fd);
414   ```
415
4166. 通过fd使用[fs.readSync](../../reference/apis-core-file-kit/js-apis-file-fs.md#readsync)接口读取这个文件内的数据,读取完成后关闭fd。
417
418   ```ts
419   let buffer = new ArrayBuffer(4096);
420   let readLen = fs.readSync(file.fd, buffer);
421   console.info('readSync data to file succeed and buffer size is:' + readLen);
422   fs.closeSync(file);
423   ```
424