最近在做项目的时候遇到需要使用网络二维码合成宣传海报图片供微信用户分享
最初计划为图片在服务器端合成然后输出到微信端使用 wx.previewImage
进行预览
但是由于某些不可描述的原因,服务器端合成图片经常需要耗时十多秒,这种情况在用户体验方面是不可接受的,所以改为 canvas 合成图片
以下是部分代码:
let canvas = document.createElement('canvas'); //创建 dom
canvas.width = 750;
canvas.height = 1334;
let ctx = canvas.getContext("2d") // 建立一个 CanvasRenderingContext2D 对象代表一个二维渲染上下文
ctx.fillStyle="#FFFFFF"; // 绘制背景色
ctx.fillRect(0,0,750,1334); // 绘制区域
document.getElementById('qrcode').onload = () => { // 等待图片加载
ctx.drawImage(document.getElementById('qrcode'),22,1094,200,200)
ctx.drawImage(document.getElementById('cover'),0,0,750,1084)
ctx.drawImage(document.getElementById('headPic'),320,1114,120,120)
ctx.font="20px sans-serif"; // 字体
ctx.fillStyle="#3a3a3a"; // 颜色
ctx.fillText(" xx 提 供 平 台 及 技 术 支 持",230,1320); // 文字
ctx.fillText("长按二维码查看更多",32,1302);
ctx.font="22px sans-serif";
ctx.fillText(this.cover_name,550,1200);
ctx.font="24px sans-serif";
ctx.fillText('店铺邀请码 :',250,1280);
ctx.rect(30,1314,180,2); // 画线
ctx.rect(560,1314,180,2);
ctx.fill();
ctx.font="28px sans-serif";
ctx.fillStyle="#E36F2B";
ctx.fillText(this.agency.inviteCode,400,1282);
this.shopPosterResource = canvas.toDataURL('image/jpeg',0.92) // 输出图片
this.showShopPoster = true
}
最终实现的大致效果是这个的:
需要注意的地方:
输出图片时,格式不宜选择png,会导致文件过大无法预览/存储,在微信中表现为长按无法识别二维码/长按无法弹出菜单/无法保存图像.
输出
jepg
图片不宜设置过低的压缩率,容易导致问题1中的错误.建议输出图片大小不大于
1M
,太大的照片在 桌面 Chrome 中也是无法复制输出的.当后端出于某些不可描述的原因无法设置
Response Headers
的Access-Control-Allow-Origin:*
,可使用 img 标签加载图片,并添加crossOrigin="Anonymous"
属性
遇到的问题:
- 通过设置 new Image() 生成的图片的 crossOrigin 属性还是无法toDataURL(), 错误提示为画布污染 原因疑似
Access-Control-Allow-Origin
导致
参考资料: