前几天接到个需求,长按图片保存到相册,该图片上有用户头像和昵称以及对应的二维码;那这就不能直接看成图片来操做了,要先把总体图片画出来;我当时用的是canvas。效果图以下:html
用canvas画图主要使用dramImage API,不太清楚的同窗能够区MDN看看:developer.mozilla.org/zh-CN/docs/…canvas
主要是用到图片URL,相对于左上角的x,y坐标以及image在canvas上绘制的宽高。小程序
那咱们开始行动了,先在html上写个canvas标签:微信小程序
<canvas canvas-id="shareCanvas" class="canvas" bindlongpress="saveImg" catchtouchmove="true" style="height: {{canvasHeight + 'rpx'}};width: {{canvasWidth + 'rpx'}};">
</canvas>
复制代码
在微信小程序上画图先要把图片路径保存到本地,这里咱们可使用wx.getImageInfo或者wx.downloadFile将图片转为本地。考虑到咱们要操做多个图片,这里对这些API进行封装:bash
getImageInfo(src) {
return new Promise((resolve, reject) => {
wx.getImageInfo({
src,
success: (res) => resolve(res),
fail: (res) => reject(res)
})
});
}
复制代码
若是你要使用downloadFile也能够,封装方法和上面同样。 封装好了那么咱们能够开始画图了,这里须要三张图片,对应的代码以下:微信
Promise
.all([
this.getImageInfo('https://cyt-resource.oss-cn-shanghai.aliyuncs.com/wximg/qrcode_bg.jpg'),
this.getImageInfo(this.data.userInfo.avatarUrl),
this.getImageInfo(this.data.qrCodeUrl)
])
.then((res) => {
const ctx = wx.createCanvasContext('shareCanvas');
ctx.drawImage(res[0].path, 0, 0, 图片宽度, 图片高度);
ctx.fillStyle = 'rgb(168, 88, 126)'; // 字体颜色
ctx.setFontSize(12); // 字体大小
ctx.fillText(this.data.userInfo.nickname, 相对于左上角的x坐标, 相对于左上角的y坐标);
ctx.drawImage(res[1].path, x坐标, y坐标, 宽, 高);
ctx.drawImage(res[2].path, x, y, width, height);
ctx.draw();
this.setData({
isDrawnImg: true
});
})
.catch((e) => {
});
复制代码
在这里要说个须要注意的坑,将图片保存到本地须要在小程序后台的downloadFile域名配置里配置好对应的域名,一个都不能落, 好比微信头像须要在downloadFile合法域名配置里加入https://wx.qlogo.cn; 另外须要提醒你们,在微信开发者工具里调试的话尽可能不要开不校验合法域名那个选项,即 微信开发
因为canvas画图须要时间,那咱们能够在等待时加个loading效果,在生成或者失败时隐藏loading,失败时还须要提示xss
wx.showLoading({
title: '图片生成中...'
});
wx.hideLoading();
wx.showToast({
title: '图片生成失败'
});
复制代码
这里使用canvasToTempFilePath API,代码以下:ide
saveImg () {
wx.canvasToTempFilePath({
canvasId: 'shareCanvas',
success: (res) => {
wx.saveImageToPhotosAlbum({
filePath: res.tempFilePath,
success: (res) => {
wx.showToast({
title: '保存成功'
});
},
fail: (res) => {
this.authorizeToWritePhotosAlbum();
}
})
}
})
},
复制代码
这里有个失败时候的操做,主要是由于取消受权后就不能使用了,这里要给个提示,让用户能够再次选择受权进行图片保存,方法以下:工具
// 受权保存图片至相册
authorizeToWritePhotosAlbum () {
wx.showModal({
title: '提示',
content: '须要您受权保存相册',
showCancel: false,
success: (res) => {
wx.openSetting({
success: (res) => {
if (settingdata.authSetting['scope.writePhotosAlbum']) {
wx.showModal({
title: '提示',
content: '获取权限成功,再次点击图片便可保存',
showCancel: false,
});
} else {
wx.showModal({
title: '提示',
content: '获取权限失败,将没法保存到相册哦~',
showCancel: false,
});
}
}
})
}
});
},
复制代码
至此,画图以及保存到相册的问题都有解决了。那么若是咱们须要适配呢,图片须要自适应。在微信小程序咱们可使用rpx进行自适应:能够看看文档 developers.weixin.qq.com/miniprogram…
由于drawImage里面的单位都是px,且不能更改,那咱们应该怎么进行自适应。能够根据设置的 设备屏幕/750*本身设置的自适应宽度(单位为rpx),好比设置宽度为600rpx,那么在drawImage里就是设备屏幕/750*600;要获取屏幕高度直接调用wx.getSystemInfo就好了,取返回结果的screenWidth;文字大小,小图片的x,y坐标均可以经过这个方法进行自适应。
我当时主要是域名配置忘了,坑了本身,而后就是受权问题(关闭后没法保存,本身懵了,没考虑到);但愿你们都能注意下,写的很差的地方但愿你们提出来,一大早写的比较匆忙,😄