这是vue2 + element + webpack写的h5项目, 打包成App之后遇到的问题。
项目用使用到echarts图表, 需要将图表保存成图片, 在电脑浏览器上用echarts自身的API就能将图片下载下来,但是打包成App之后, 保存到手机相册, 一直显示保存失败
以下将功能实现参考的文章:
(1) vue+h5 移动端保存图片到手机相册 : 这个文章的代码我是直接拿来使用的, 他利用的是html5 plus, plus可以在App上使用,在电脑浏览器上显示会报错的
(2)如何将base64图片转化为URL格式: 这里将echarts图表保存图片我用的是echarts的API – getDataURL(), getDataURL返回的是图片是base64格式的
(3) html5 plus 图片下载保存到手机相册: 这篇文章和(1) 的代码是一样,只是这个博主把html5 plus的网址和他自己写的demo放出来了, 我没用到,但是说不定之后会用到,就一起把他们贴出来吧
过程
在经过我踩雷尝试之后, 功能实现的步骤分为四步:
(1) 使用getDataURL()将echarts图表保存为base64格式的图片
(2) 将base64格式的图片转换为file文件
(3) 将file文件上传至腾讯云生成 https://xxxxx 的图片链接
(4) 使用plus.downloader.createDownload将图片保存
至于为什么多了个步骤3是因为plus.downloader.createDownload的url参数仅支持网络资源地址(支持http或https协议); 如果有别的能将base64转化为 http网络链接的话,可以滴我! 我不会
四个步骤的代码依次如下:
// 老项目用的vue2, this.myChartP 为echarts实例
function getBase64() {
const src = this.myChartP.getDataURL({
pixelRatio: 2,
backgroundColor: "#fff"
});
return src;
}
// base64 转化为文件
function base64ImgtoFile(dataurl, filename = "file") {
//将base64格式分割:['data:image/png;base64','XXXX']
const arr = dataurl.split(",");
// .*? 表示匹配任意字符到下一个符合条件的字符 刚好匹配到:
// image/png
const mime = arr[0].match(/:(.*?);/)[1]; //image/png
//[image,png] 获取图片类型后缀
const suffix = mime.split("/")[1]; //png
const bstr = atob(arr[1]); //atob() 方法用于解码使用 base-64 编码的字符串
let n = bstr.length;
const u8arr = new Uint8Array(n);
while (n--) {
u8arr[n] = bstr.charCodeAt(n);
}
return new File([u8arr], `${filename + Date.now()}.${suffix}`, {
type: mime
});
}
// 将文件上传至腾讯云
function upload(res) {
console.log("upload res.name", res.name);
cos.putObject(
{
Bucket: "cute-ghost-1312673588" /* 填入您自己的存储桶,必须字段 */,
Region: "ap-nanjing" /* 存储桶所在地域,例如ap-beijing,必须字段 */,
Key:
res.name /* 存储在桶里的对象键(例如1.jpg,a/b/test.txt),必须字段 */,
StorageClass: "STANDARD",
Body: res, // 上传文件对象
onProgress: function(progressData) {
console.log(JSON.stringify(progressData));
this.percent = progressData.percent * 100;
}
},
(err, data) => {
// 上传成功之后
if (data.statusCode === 200) {
console.log("this", this);
const imageURL = `https://${data.Location}`;
console.log("imageURL", imageURL);
// 上传成功之后可以将其下载
this.download(imageURL);
}
}
);
}
function download(url) {
// url为图片地址(上传到后台,拿到链接)
// 创建下载任务
plus.nativeUI.showWaiting("加载中...");
// plus.downloader.createDownload中的url,指的是要下载文件的url地址,仅支持网络资源地址,支持http或https协议。
var dtask = plus.downloader.createDownload(url, {}, function(d, status) {
// 下载完成
if (status == 200) {
console.log("下载成功,文件保存在" + d.filename);
plus.gallery.save(
d.filename,
function() {
//保存到相册方法
plus.nativeUI.closeWaiting();
plus.nativeUI.toast("保存成功");
},
function() {
plus.nativeUI.closeWaiting();
plus.nativeUI.toast("保存失败,请重试!");
}
);
} else {
plus.nativeUI.closeWaiting();
plus.nativeUI.toast("保存失败,请重试!");
}
});
dtask.start();
}
补充: 腾讯云的使用
- 下载
npm i cos-js-sdk-v5 --save
- 实例化cos对象
// 下面的代码是固定写法
const COS = require('cos-js-sdk-v5')
// 填写自己腾讯云cos中的key和id (密钥)
const cos = new COS({
SecretId: 'xxx', // 身份识别ID
SecretKey: 'xxx' // 身份秘钥
})
- 根据腾讯云文档地址,上传对象:
cos.putObject({
Bucket: 'examplebucket-1250000000', /* 填入您自己的存储桶,必须字段 */
Region: 'COS_REGION', /* 存储桶所在地域,例如ap-beijing,必须字段 */
Key: '1.jpg', /* 存储在桶里的对象键(例如1.jpg,a/b/test.txt),必须字段 */
StorageClass: 'STANDARD',
Body: fileObject, // 上传文件对象
onProgress: function(progressData) {
console.log(JSON.stringify(progressData));
}
}, function(err, data) { // !注意: 如果将这段代码放到vue的methods中, 需要将这个函数,改成箭头函数,否则将无法访问data里面的数据
console.log(err || data);
});