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_ONLY。 409 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