Canvas To Image

SHOYUF

最近在做项目的时候遇到需要使用网络二维码合成宣传海报图片供微信用户分享

最初计划为图片在服务器端合成然后输出到微信端使用 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
}

最终实现的大致效果是这个的:
效果图
需要注意的地方:

  1. 输出图片时,格式不宜选择png,会导致文件过大无法预览/存储,在微信中表现为长按无法识别二维码/长按无法弹出菜单/无法保存图像.

  2. 输出 jepg 图片不宜设置过低的压缩率,容易导致问题1中的错误.

  3. 建议输出图片大小不大于 1M ,太大的照片在 桌面 Chrome 中也是无法复制输出的.

  4. 当后端出于某些不可描述的原因无法设置Response HeadersAccess-Control-Allow-Origin:*,可使用 img 标签加载图片,并添加crossOrigin="Anonymous"属性

遇到的问题:

  1. 通过设置 new Image() 生成的图片的 crossOrigin 属性还是无法toDataURL(), 错误提示为画布污染 原因疑似 Access-Control-Allow-Origin导致

参考资料:

  1. HTML5 CANVAS 实现图片压缩和裁切
  2. MDN 启用了 CORS 的图片

本站使用署名 4.0 国际 (CC BY 4.0) 创作共享协议,转载请署名,图片请转存。

提醒:本文最后更新于 686 天前,文中所描述的信息可能已发生改变,请谨慎使用。