写点什么

【HarmonyOS】SaveButton 保存图片

作者:zhongcx
  • 2024-10-18
    北京
  • 本文字数:4851 字

    阅读完需:约 16 分钟

SaveButton 组件把图片显示到相册中的方法 demo,支持组件截图、url 网络图片、base64 格式图片。

注意事项:

1、样式不支持自定义图标,试过用 opacity 修改透明度,然后添加背景来实现自定义样式,结果也失败了,opacity(1)点击生效,opacity(0.9)后点击按钮就不生效了。

2、如果带 Scroll 时,下载按钮被遮挡一部分,也无法保存到相册。

比如下面这样遮挡一点点下载按钮后,点击就没办法保存到相册了。

import photoAccessHelper from '@ohos.file.photoAccessHelper';import fs from '@ohos.file.fs';import { common } from '@kit.AbilityKit';import { componentSnapshot, promptAction } from '@kit.ArkUI';import { image } from '@kit.ImageKit';import { BusinessError } from '@kit.BasicServicesKit';import { http } from '@kit.NetworkKit';import { util } from '@kit.ArkTS';
@Entry@Componentstruct Page09 { inviteQrCodeID: string = "inviteQrCodeID" @State imageUrl: string = "httpsxxxx.jpg" @State base64Str: string = 'data:image/png;base64,iVBO........' build() { Scroll() { Column({ space: 10 }) { Column({ space: 10 }) { Text('下载组件截图图片到相册')
Column() { Column() { Text('标题测试').fontSize('36lpx').height('120lpx').fontColor("#2E2E2E") QRCode('httpswww.huxxxx.com') .width('300lpx') .height('300lpx') .margin({ top: '25lpx' }) .draggable(false) .width(140) .height(140) }.padding({ left: '42lpx', right: '42lpx', bottom: '20lpx' })
Text('点按下载保存至相册') .textAlign(TextAlign.Center) .padding({ left: '125lpx', right: '125lpx' }) .fontColor("#4B4B4B") .fontSize('32lpx') .margin({ bottom: '70lpx' }) } .id(this.inviteQrCodeID) .padding('20lpx') .margin({ top: '30lpx', bottom: '30lpx' }) .backgroundColor(Color.White) .borderRadius('30lpx') .alignItems(HorizontalAlign.Center) .justifyContent(FlexAlign.Center)
SaveButton().onClick(async (event: ClickEvent, result: SaveButtonOnClickResult) => { if (result === SaveButtonOnClickResult.SUCCESS) { const context: common.UIAbilityContext = getContext(this) as common.UIAbilityContext; // 免去权限申请和权限请求等环节,获得临时授权,保存对应图片 let helper = photoAccessHelper.getPhotoAccessHelper(context); try { // onClick触发后5秒内通过createAsset接口创建图片文件,5秒后createAsset权限收回。 let uri = await helper.createAsset(photoAccessHelper.PhotoType.IMAGE, 'jpg'); // 使用uri打开文件,可以持续写入内容,写入过程不受时间限制 let file = await fs.open(uri, fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE); componentSnapshot.get(this.inviteQrCodeID).then((pixelMap) => { let packOpts: image.PackingOption = { format: 'image/png', quality: 100 } const imagePacker: image.ImagePacker = image.createImagePacker(); return imagePacker.packToFile(pixelMap, file.fd, packOpts).finally(() => { imagePacker.release(); //释放 fs.close(file.fd); promptAction.showToast({ message: '图片已保存至相册', duration: 2000 }); }); }) } catch (error) { const err: BusinessError = error as BusinessError; console.error(`Failed to save photo. Code is ${err.code}, message is ${err.message}`); }
} else { promptAction.showToast({ message: '设置权限失败!', duration: 2000 }); } }) }.borderWidth(1).borderStyle(BorderStyle.Dotted).backgroundColor(Color.Pink).padding('50lpx')
Column({ space: 10 }) { Text('下载网络图片到相册') /** * 需要在 src/main/module.json5 * 添加网络权限 * { "module": { "requestPermissions": [ { "name": "ohos.permission.INTERNET" }, ], */ Image(this.imageUrl).width('100lpx')
SaveButton().onClick(async (event: ClickEvent, result: SaveButtonOnClickResult) => { if (result === SaveButtonOnClickResult.SUCCESS) { const context: common.UIAbilityContext = getContext(this) as common.UIAbilityContext; // 免去权限申请和权限请求等环节,获得临时授权,保存对应图片 // savePhotoToGallery(context); let helper = photoAccessHelper.getPhotoAccessHelper(context); try { http.createHttp().request( this.imageUrl, { expectDataType: http.HttpDataType.ARRAY_BUFFER } ).then(async (res) => { console.info('res', JSON.stringify(res)) // 将图片资源转为像素图(PixelMap) let pixelMap = await image.createImageSource(res.result as ArrayBuffer).createPixelMap()
// onClick触发后5秒内通过createAsset接口创建图片文件,5秒后createAsset权限收回。 let uri = await helper.createAsset(photoAccessHelper.PhotoType.IMAGE, 'jpg'); // 使用uri打开文件,可以持续写入内容,写入过程不受时间限制 let file = await fs.open(uri, fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE); let packOpts: image.PackingOption = { format: 'image/png', quality: 100 } const imagePacker: image.ImagePacker = image.createImagePacker(); return imagePacker.packToFile(pixelMap, file.fd, packOpts).finally(() => { imagePacker.release(); //释放 fs.close(file.fd); promptAction.showToast({ message: '图片已保存至相册', duration: 2000 }); }); }).catch(() => { console.info('catch') }) } catch (error) { const err: BusinessError = error as BusinessError; console.error(`Failed to save photo. Code is ${err.code}, message is ${err.message}`); }
} else { promptAction.showToast({ message: '设置权限失败!', duration: 2000 }); } }) }.borderWidth(1).borderStyle(BorderStyle.Dotted).backgroundColor(Color.Pink).padding('50lpx')
Column({ space: 10 }) { Text('下载base64图片到相册') Text('注意1:有些base64的格式图片显示不出来,\n是因为前缀没加data:image/png;base64,').textAlign(TextAlign.Center) Text("注意2:下载到相册的base64字符串不能有'data:image/jpeg;base64,'这样的前缀。所以我这里用正则去掉了前缀").textAlign(TextAlign.Center) SaveButton().onClick(async (event: ClickEvent, result: SaveButtonOnClickResult) => { if (result === SaveButtonOnClickResult.SUCCESS) { const context: common.UIAbilityContext = getContext(this) as common.UIAbilityContext; // 免去权限申请和权限请求等环节,获得临时授权,保存对应图片 // savePhotoToGallery(context); let helper = photoAccessHelper.getPhotoAccessHelper(context); try { // 正则表达式用于匹配 "data:image/*;base64," 这样的前缀 const prefixRegex = /^data:image\/[a-zA-Z]+;base64,/; // 使用 replace 方法去除匹配到的前缀 let base64String = this.base64Str.replace(prefixRegex, '') let buffer: ArrayBuffer = new util.Base64Helper().decodeSync(base64String, util.Type.MIME).buffer as ArrayBuffer; let imageSource = image.createImageSource(buffer); let pixelMap = await imageSource.createPixelMap({ editable: true });
let opts: image.PackingOption = { format: "image/jpeg", quality: 100 }; // onClick触发后5秒内通过createAsset接口创建图片文件,5秒后createAsset权限收回。 let uri = await helper.createAsset(photoAccessHelper.PhotoType.IMAGE, 'jpg'); // 使用uri打开文件,可以持续写入内容,写入过程不受时间限制 let file = await fs.open(uri, fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE); let packOpts: image.PackingOption = { format: 'image/png', quality: 100 } const imagePacker: image.ImagePacker = image.createImagePacker(); return imagePacker.packToFile(pixelMap, file.fd, packOpts).finally(() => { imagePacker.release(); //释放 fs.close(file.fd); promptAction.showToast({ message: '图片已保存至相册', duration: 2000 }); }); } catch (error) { const err: BusinessError = error as BusinessError; console.error(`Failed to save photo. Code is ${err.code}, message is ${err.message}`); }
} else { console.info(`result:${JSON.stringify(result)}`) promptAction.showToast({ message: '设置权限失败!', duration: 2000 }); } }) } .borderWidth(1).borderStyle(BorderStyle.Dotted).backgroundColor(Color.Pink).padding('50lpx')
}.width('100%') }.width('100%') }}
复制代码


用户头像

zhongcx

关注

还未添加个人签名 2024-09-27 加入

还未添加个人简介

评论

发布
暂无评论
【HarmonyOS】SaveButton 保存图片_zhongcx_InfoQ写作社区