# 序言 前不久做一个小程序生成产品海报功能,用canvas画图将产品信息和二维码信息生成图片,再让用户保存图片到本地,分享到朋友圈。本地调试正常,海报生成也正常。但是真机上却出了问题,原本应该正常显示的产品封面却是空白的。 # 解决过程 下面是画图代码 ```js 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) } }) }, ``` 生成海报: ![生成海报](https://img-blog.csdnimg.cn/2019032111130095.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM3MjQ2MzUx,size_16,color_FFFFFF,t_70) 保存后: ![海报](https://img-blog.csdnimg.cn/20190321111329252.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM3MjQ2MzUx,size_16,color_FFFFFF,t_70) 真机调试后结果: ![真机测试](https://img-blog.csdnimg.cn/20190321112459394.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM3MjQ2MzUx,size_16,color_FFFFFF,t_70) 查微信文档上没任何说明,百度后得知图片需要下载下来再调接口drawImage,我的图片是网络图片,微信无法使用,需要先调接口 downloadFilestoreImage,然后拿到临时目录路径,这才是drawImage的第一个参数,其实微信文档虽然没写,但是它引用的参数res.tempFilePaths[0],也说明了问题,只是当时我不知道而已。 ```js const ctx = wx.createCanvasContext('myCanvas') wx.chooseImage({ success(res) { ctx.drawImage(res.tempFilePaths[0], 0, 0, 150, 100) ctx.draw() } }) ``` # 解决方法 ## 一、图片在当前页未加载,需重新下载 这种情况是我的产品详情页没有加载封面图片,只放上了轮播图,所以需要下载图片 下载时要注意调用的图片地址是否为https,且加到后台配置里面了,否则会报错下载不成功 ```js //获取海报产品图 //微信只能读取本地图片,只能先下载下来,读取临时目录,再去用canvas画下来 downloadFilestoreImage: function (img) { console.log(img); var that = this; wx.downloadFile({ url: img, success: function (res) { that.setData({ storeImage: res.tempFilePath }) } }); }, ``` ## 二、图片加载了,获取图片信息 这种情况是图片加载过了,并在本地已经有临时目录,所以直接调getImageInfo ```js //获取网络图片临时目录path wx.getImageInfo({ src: that.data.goods.cover, success: function (res) { //res.path是网络图片的本地地址 let Path = res.path; that.setData({ storeImage: Path }) }, fail: function (res) { } }); ``` >完美撒花,这只是踩坑之一,如果有需要生成产品海报源码贴出来的,或者我找机会写一篇关于这个的博文,可以下面留言。 未经允许不得转载:张浩博客 » 小程序drawImage接口canvas生成产品海报失败
评论前必须登录!
立即登录 注册