【HarmonyOS】 鸿蒙保存图片或视频到相册

前言

鸿蒙中保存图片或者视频,或者其他媒体文件到设备的媒体库,可以是相册,也可以是文件管理等。共有两种方式:

需要应用申请受限权限,获取文件读写的权限(调用需要ohos.permission.READ_IMAGEVIDEO和ohos.permission.WRITE_IMAGEVIDEO的权限),这样就可以将媒体资源(图片or视频or等等)保存到媒体库。

通过安全控件,用户触发后表示同意,可以临时授权给应用就行保存处理。

关于第二种安全控件,又分为saveButton保存按钮 和showAssetsCreationDialog授权弹框两种形式。前者的按钮样式不能自定义,所以后者以弹框的形式,让用户操作,触发入口的样式,应用就可以自定义了。后者算是前者的一种替代补充。

一、保存图片和视频授权示例

需要申请"ohos.permission.READ_IMAGEVIDEO"和"ohos.permission.WRITE_IMAGEVIDEO"权限。该权限是管制权限,需要你的应用去通过场景申请【申请使用受限权限】

配置权限READ_IMAGEVIDEO,WRITE_IMAGEVIDEO

dart

复制代码

"requestPermissions": [

{

"name": "ohos.permission.READ_IMAGEVIDEO",

"usedScene": {

"abilities": [

"EntryAbility"

],

"when": "inuse"

},

"reason": "$string:CAMERA"

},

{

"name": "ohos.permission.WRITE_IMAGEVIDEO",

"usedScene": {

"abilities": [

"EntryAbility"

],

"when": "inuse"

},

"reason": "$string:CAMERA"

}

]

向用户申请权限

dart

复制代码

// 创建申请权限明细

async reqPermissionsFromUser(): Promise {

let context = getContext() as common.UIAbilityContext;

let atManager = abilityAccessCtrl.createAtManager();

let grantStatus = await atManager.requestPermissionsFromUser(context, ['ohos.permission.READ_IMAGEVIDEO','ohos.permission.WRITE_IMAGEVIDEO']);

return grantStatus.authResults;

}

// 用户申请权限

async requestPermission() {

let grantStatus = await this.reqPermissionsFromUser();

for (let i = 0; i < grantStatus.length; i++) {

if (grantStatus[i] === 0) {

// 用户授权,可以继续访问目标操作

}

}

}

保存图片到媒体库

dart

复制代码

public async savePicture(buffer: ArrayBuffer): Promise {

let helper : photoAccessHelper.PhotoAccessHelper = photoAccessHelper.getPhotoAccessHelper(getContext(this) as common.UIAbilityContext);

let options: photoAccessHelper.CreateOptions = {

title: Date.now().toString()

};

let photoUri: string = await helper.createAsset(photoAccessHelper.PhotoType.IMAGE, 'jpg', options);

console.info(photoUri)

// createAsset的调用需要ohos.permission.READ_IMAGEVIDEO和ohos.permission.WRITE_IMAGEVIDEO的权限

let file: fs.File = fs.openSync(photoUri, fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE);

await fs.write(file.fd, buffer);

fs.closeSync(file);

}

二、saveButton示例

dart

复制代码

import { photoAccessHelper } from '@kit.MediaLibraryKit';

@Entry

@Component

struct saveButtonExample {

saveButtonOptions: SaveButtonOptions = {

icon: SaveIconStyle.FULL_FILLED,

text: SaveDescription.SAVE_IMAGE,

buttonType: ButtonType.Capsule

} // 设置安全控件按钮属性

build() {

Row() {

Column() {

SaveButton(this.saveButtonOptions) // 创建安全控件按钮

.onClick(async (event, result: SaveButtonOnClickResult) => {

if (result == SaveButtonOnClickResult.SUCCESS) {

try {

let context = getContext();

let phAccessHelper = photoAccessHelper.getPhotoAccessHelper(context);

// 需要确保fileUri对应的资源存在

let fileUri = 'file://com.example.temptest/data/storage/el2/base/haps/entry/files/test.jpg';

let assetChangeRequest: photoAccessHelper.MediaAssetChangeRequest = photoAccessHelper.MediaAssetChangeRequest.createImageAssetRequest(context, fileUri);

await phAccessHelper.applyChanges(assetChangeRequest);

console.info('createAsset successfully, uri: ' + assetChangeRequest.getAsset().uri);

} catch (err) {

console.error(`create asset failed with error: ${err.code}, ${err.message}`);

}

} else {

console.error('SaveButtonOnClickResult create asset failed');

}

})

}

.width('100%')

}

.height('100%')

}

}

三、 showAssetsCreationDialog示例

dart

复制代码

import { photoAccessHelper } from '@kit.MediaLibraryKit';

import { fileIo } from '@kit.CoreFileKit';

let context = getContext(this);

let phAccessHelper = photoAccessHelper.getPhotoAccessHelper(context);

async function showAssetsCreationDialogExample() {

try {

// 指定待保存到媒体库的位于应用沙箱的图片uri

let srcFileUri = 'file://com.example.temptest/data/storage/el2/base/haps/entry/files/test.jpg';

let srcFileUris: Array = [

srcFileUri

];

// 指定待保存照片的创建选项,包括文件后缀和照片类型,标题和照片子类型可选

let photoCreationConfigs: Array = [

{

title: 'test', // 可选

fileNameExtension: 'jpg',

photoType: photoAccessHelper.PhotoType.IMAGE,

subtype: photoAccessHelper.PhotoSubtype.DEFAULT, // 可选

}

];

// 基于弹窗授权的方式获取媒体库的目标uri

let desFileUris: Array = await phAccessHelper.showAssetsCreationDialog(srcFileUris, photoCreationConfigs);

// 将来源于应用沙箱的照片内容写入媒体库的目标uri

let desFile: fileIo.File = await fileIo.open(desFileUris[0], fileIo.OpenMode.WRITE_ONLY);

let srcFile: fileIo.File = await fileIo.open(srcFileUri, fileIo.OpenMode.READ_ONLY);

await fileIo.copyFile(srcFile.fd, desFile.fd);

fileIo.closeSync(srcFile);

fileIo.closeSync(desFile);

console.info('create asset by dialog successfully');

} catch (err) {

console.error(`failed to create asset by dialog successfully errCode is: ${err.code}, ${err.message}`);

}

}

注意:

1. 使用createAsset需要指定是视频还是图片, fileio.open并不校验文件内容

2. 使用createImageAssetRequest接口,如果要保存视频需要用createVideoeAssetRequest

或者还可以直接使用createAssetRequest和addResource的方式