小程序drawImage接口canvas生成产品海报失败
序言
前不久做一个小程序生成产品海报功能,用canvas画图将产品信息和二维码信息生成图片,再让用户保存图片到本地,分享到朋友圈。本地调试正常,海报生成也正常。但是真机上却出了问题,原本应该正常显示的产品封面却是空白的。
解决过程
下面是画图代码
goPoster: function () {
var that = this;
var uid = wx.getStorageSync('uid')
var token = wx.getStorageSync('token')
wx.showLoading({
title: '海报生成中',
mask: true,
})
var data={
uid:uid,
id:this.data.goods.id,
token:token
}
that.setData({ canvasStatus: true });
// 第一张为背景图(本地),第二张为产品图(网络)
const arr2 = ['/images/posterbackgd.png', that.data.storeImage];
http.postReq('WxCode/creatLimitCode.html', data, function (res) {
if (res.code == 10000) {
const msgPromotionCode = res.data;
const ctx = wx.createCanvasContext('myCanvas');
ctx.clearRect(0, 0, 0, 0);
wx.downloadFile({
url: that.setDomain(msgPromotionCode),
success: function (res) {
arr2[2] = res.tempFilePath;
wx.getImageInfo({
src: arr2[0],
success: function (res) {
const WIDTH = res.width;
const HEIGHT = res.height;
console.log(WIDTH);
ctx.drawImage(arr2[0], 0, 0, WIDTH, HEIGHT);
ctx.drawImage(arr2[1], 0, 0, WIDTH, WIDTH);
ctx.save();
let r = 90;
let d = r * 2;
let cx = 40;
let cy = 990;
ctx.arc(cx + r, cy + r, r, 0, 2 * Math.PI);
ctx.clip();
ctx.drawImage(arr2[2], cx, cy, d, d);
ctx.restore();
const CONTENT_ROW_LENGTH = 32;
let [contentLeng, contentArray, contentRows] = that.textByteLength(that.data.goods.title, CONTENT_ROW_LENGTH);
ctx.setTextAlign('center')
ctx.setFontSize(32);
let contentHh = 32 * 1.3;
for (let m = 0; m < contentArray.length; m++) {
ctx.fillText(contentArray[m], WIDTH / 2, 820 + contentHh * m);
}
ctx.setTextAlign('center')
ctx.setFontSize(48);
ctx.setFillStyle('red');
ctx.fillText('¥' + that.data.goods.price, WIDTH / 2, 890 + contentHh);
ctx.draw(true, function () {
wx.canvasToTempFilePath({
canvasId: 'myCanvas',
fileType: 'png',
destWidth: WIDTH,
destHeight: HEIGHT,
success: function (res) {
wx.hideLoading();
that.setData({
posterImage: res.tempFilePath,
posterImageStatus: true,
canvasStatus: false,
actionSheetHidden: !that.data.actionSheetHidden
})
}
})
});
},
})
}
});
} else {
util.tips(res.codeMsg)
}
})
},
生成海报:
保存后:
真机调试后结果:
查微信文档上没任何说明,百度后得知图片需要下载下来再调接口drawImage,我的图片是网络图片,微信无法使用,需要先调接口 downloadFilestoreImage,然后拿到临时目录路径,这才是drawImage的第一个参数,其实微信文档虽然没写,但是它引用的参数res.tempFilePaths[0],也说明了问题,只是当时我不知道而已。
const ctx = wx.createCanvasContext('myCanvas')
wx.chooseImage({
success(res) {
ctx.drawImage(res.tempFilePaths[0], 0, 0, 150, 100)
ctx.draw()
}
})
解决方法
一、图片在当前页未加载,需重新下载
这种情况是我的产品详情页没有加载封面图片,只放上了轮播图,所以需要下载图片
下载时要注意调用的图片地址是否为https,且加到后台配置里面了,否则会报错下载不成功
//获取海报产品图
//微信只能读取本地图片,只能先下载下来,读取临时目录,再去用canvas画下来
downloadFilestoreImage: function (img) {
console.log(img);
var that = this;
wx.downloadFile({
url: img,
success: function (res) {
that.setData({
storeImage: res.tempFilePath
})
}
});
},
二、图片加载了,获取图片信息
这种情况是图片加载过了,并在本地已经有临时目录,所以直接调getImageInfo
//获取网络图片临时目录path
wx.getImageInfo({
src: that.data.goods.cover,
success: function (res) {
//res.path是网络图片的本地地址
let Path = res.path;
that.setData({
storeImage: Path
})
},
fail: function (res) {
}
});
完美撒花,这只是踩坑之一,如果有需要生成产品海报源码贴出来的,或者我找机会写一篇关于这个的博文,可以下面留言。