背景
最近产品提了一个小程序保存图片的功能。小程序预览本来是支持长按图片保存的,但是考虑到部分用户不知道这个功能,只能单做一个保存图片的按钮。
问题
保存图片的功能看起来是很简单的。但我做的时候遇到了下面几个问题。
- 图片url
wx.saveImageToPhotosAlbum方法只支持保存本地路径,不支持网络路径,需要使用wx.downloadFile下载文件资源到本地,取到图片本地路径。
- 兼容性问题
兼容性问题指的是,我们项目的要保存的图片是一个GET接口地址,返回图片的文件流,这样它的url就不是标准的png/jpg后缀格式,经试验,在微信开发者工具和苹果手机上都可以保存,但在安卓手机上会报错,“saveImageToPhotosAlbum:fail invalid file type”,其实就是图片类型错误。我们可以在wx.downloadFile时加上filePath属性,手动加上图片后缀。代码如下所示:
saveImageToPhotosAlbum() {
const that = this;
wx.downloadFile({
url: this.qrCode,
filePath: `${wx.env.USER_DATA_PATH}/${Date.now()}.jpg`,
success(result) {
wx.saveImageToPhotosAlbum({
filePath: result.filePath,
success(res) {
that.$toast('图片保存成功', 'success');
},
fail(err) {
console.log(err);
that.$toast('图片保存失败');
}
});
}
});
}
- 授权问题
在保存图片时小程序会发起「保存图片」授权。我们需要判断三种情况:未授权、拒绝授权和授权成功。可以使用wx.getSetting方法获取到用户的授权情况。代码如下:
saveImageEvent() {
const settingId = 'scope.writePhotosAlbum';
getAuthSetting('authSetting', settingId).then(writePhotosAlbum => {
const that = this;
console.log('writePhotosAlbum', writePhotosAlbum);
if (writePhotosAlbum === undefined) { // 未授权过,申请授权
wx.authorize({
scope: settingId,
success() {
that.saveImageToPhotosAlbum();
},
fail(res) {
that.$toast('授权失败');
}
});
} else if (writePhotosAlbum === false) { // 拒绝授权,打开授权设置
wx.openSetting({
success(res) {
if (res.authSetting[settingId]) {
that.saveImageToPhotosAlbum();
}
},
fail() {
that.$toast('授权失败');
}
});
} else {
this.saveImageToPhotosAlbum();
}
});
}
/**
* 获取用户权限设置
* @param {*} settingType 设置类型:authSetting、subscriptionsSetting
* @param {*} settingId 设置ID:address、writePhotosAlbum等
*/
export function getAuthSetting(settingType, settingId) {
return new Promise((resolve, reject) => {
wx.getSetting({
withSubscriptions: true,
success(response) {
console.log(response);
resolve(response[settingType][settingId]);
}
});
}).catch(res => {
console.log(res);
});
}