Search K
Appearance
Appearance
保存图片到相册常规的方式需要申请'ohos.permission.WRITE_IMAGEVIDEO'
权限,这个权限是ACL
权限,申请是比较麻烦的,官方给到了另外一种方式:使用安全控件创建媒体资源
,使用安全控件创建媒体资源无需在应用中申请相册管理模块权限'ohos.permission.WRITE_IMAGEVIDEO'
,详情请参考安全控件的保存控件。
开发步骤: 1、设置安全控件按钮属性。
2、创建安全控件按钮。
3、调用MediaAssetChangeRequest.createImageAssetRequest
和PhotoAccessHelper.applyChanges
接口创建图片资源。
import { photoAccessHelper } from '@kit.MediaLibraryKit';
@Entry
@Component
struct Index {
@State message: string = 'Hello World'
@State saveButtonOptions: SaveButtonOptions = {
icon: SaveIconStyle.FULL_FILLED,
text: SaveDescription.SAVE_IMAGE,
buttonType: ButtonType.Capsule
} // 设置安全控件按钮属性
build() {
Row() {
Column() {
Text(this.message)
.fontSize(50)
.fontWeight(FontWeight.Bold)
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%')
}
}
如果保存的图片是pixmap
或者ArrayBuffer
可以用以下工具类函数进行转换
/**
* 保存pixmap到沙箱,并且返回沙箱uri
* @param pixmap 图片map
* @param filesDir 保存的目录
*/
public static savePixmap2SystemFileManager(pixmap: image.PixelMap, filesDir: string): Promise<string> {
return new Promise(async (resolve, reject) => {
try {
let url = filesDir + `/${DateUtil.getTimeStamp()}.png`
if (!pixmap) {
return;
}
const imgBuffer = await CommonUtil.transferPixelMap2Buffer(pixmap);
const file = fileIo.openSync(url,
fileIo.OpenMode.READ_WRITE | fileIo.OpenMode.CREATE);
await fileIo.write(file.fd, imgBuffer);
await fileIo.close(file.fd);
resolve(url)
} catch (e) {
reject(e)
}
})
}
/**
* 将pixelMap转成图片格式,以流的形式输出
* @param pixelMap
* @returns
*/
public static transferPixelMap2Buffer(pixelMap: image.PixelMap): Promise<ArrayBuffer> {
return new Promise((resolve, reject) => {
/**
* 设置打包参数
* format:图片打包格式,只支持 jpg 和 webp
* quality:JPEG 编码输出图片质量
* bufferSize:图片大小,默认 10M
*/
let packOpts: image.PackingOption = { format: 'image/jpeg', quality: 98 };
// 创建ImagePacker实例
const imagePackerApi = image.createImagePacker();
imagePackerApi.packing(pixelMap, packOpts).then((buffer: ArrayBuffer) => {
resolve(buffer);
}).catch((err: BusinessError) => {
reject();
})
})
}
需要注意这里创建filePath
的时候,fs.statSync(pathDir + BaseConstants.fileDir).isDirectory();
这行判断目录是否存在的代码会报错,只能在这里以try-catch
的方式判断目录文件夹是否存在
/**
* 保存图片资源到相册
* @param context
* @param buff
* @returns
*/
public static async saveAlbumAbility(context: common.UIAbilityContext, pixmap: image.PixelMap): Promise<void> {
const permissions: Array<Permissions> =
["ohos.permission.INTERNET", "ohos.permission.WRITE_IMAGEVIDEO", "ohos.permission.READ_IMAGEVIDEO"];
const result = await PermissionSetting.checkPermissions(context as common.UIAbilityContext,
permissions)
if (result.flag) {
return new Promise(async (resolve, reject) => {
try {
// 创建写入的路径
let pathDir = context.filesDir;
let filePath = pathDir + BaseConstants.fileDir
try {
let isDirectory = fs.statSync(pathDir + BaseConstants.fileDir).isDirectory();
} catch (err) {
// 代表该文件夹不存在需要创建
if (err.code === 13900002) {
fs.mkdirSync(pathDir + BaseConstants.fileDir);
}
}
const uri = await CommonUtil.savePixmap2SystemFileManager(pixmap, filePath)
const fileUrl: string = fileUri.getUriFromPath(uri);
// 这种方式不需要权限
let phAccessHelper = photoAccessHelper.getPhotoAccessHelper(context);
// 需要确保fileUri对应的资源存在
let assetChangeRequest: photoAccessHelper.MediaAssetChangeRequest =
photoAccessHelper.MediaAssetChangeRequest.createImageAssetRequest(context, fileUrl);
await phAccessHelper.applyChanges(assetChangeRequest);
// 通过getPhotoAccessHelper写入路径(这种方式也可以进行保存)
// let helper = photoAccessHelper.getPhotoAccessHelper(context);
// let uri = await helper.createAsset(photoAccessHelper.PhotoType.IMAGE, 'jpg')
// let file = await fileIo.open(uri, fileIo.OpenMode.READ_WRITE | fileIo.OpenMode.CREATE)
// // 写入文件
// await fileIo.write(file.fd, buff);
// // 关闭文件
// await fileIo.close(file.fd);
resolve()
} catch (error) {
Logger.info("save image fail", error)
reject()
}
})
} else {
ServiceAccessFilter.showToast("申请权限失败")
}
}