图片合成

2017-03-06  本文已影响334人  大淀桑浮不起來

前段时间遇到产品一个需求,在移动端上合成生成二维码,并且合成背景图和二维码给用户保存;

当时我在想,链接拼接生成二维码这个没什么,图片合成在移动端来做,结果后端的小伙伴说他们有现成的方案,他们合成,最后也就让后端做了;

最后想想,前端其实做起来也很方便啊,搞起!

形式一片大好

合成,也就是将一个背景图,一个二维码图放在一个容器内,那么canvas不是有一个drawImage可以把图片给画进去么?最后再照葫芦画瓢画二维码,最后toDataURL把base64编码的图片信息导出给img标签不就OK啦!

// bgSize,qrSize为对应图的尺寸
// bgUrl,qrUrl为对应图的地址
// qrX,qrY为偏移值,target为你展示的img标签的class或者id
const canvas = document.createElement("canvas");
if (canvas.getContext) {
  canvas.width = bgSize; 
  canvas.height = bgSize;
  let ctx = canvas.getContext('2d');
  ctx.fillRect(0 ,0, bgSize, bgSize);
  ctx.fillStyle='transparent';
  ctx.fill();
  let bgImg = new Image();
  // bgImg.crossOrigin = "anonymous";
  bgImg.src = bgUrl;
  bgImg.addEventListener("load", ()=> {
    ctx.drawImage(bgImg, 0, 0, bgSize, bgSize);
    let qrImg = new Image();
    // qrImg.crossOrigin = "anonymous";
    qrImg.src = qrUrl;   
    qrImg.addEventListener("load", ()=> {
      ctx.drawImage(qrImg, qrX, qrY, qrSize, qrSize);
      document.querySelector(target).src = canvas.toDataURL("image/png");
    });
  });   
};
结果 报错了

这是为什么呢?去搜索了很多,很多人说什么canvas不能使用跨域图片,问题都集中在跨域上;

跨域说对了一半,并不是canvas不能使用跨域图片,而是在用没有跨域权限图片导出信息时会报错,Canvas确实是为了安全性考虑,当绘制了外部图片后它会变成只可写不可读的状态,getImageData、toDataURL之类的试图读取数据的方法全都无法使用;

img.crossOrigin = "anonymous";

之后呢,其实也就是让前端开启了图片的跨域使用,为图片服务添加CROS(跨域)支持,具体方法是在图片的返回的header中添加Access-Control-Allow-Origin:*,同时在请求图片时,为image元素设置crossOrigin="" 属性设置为空字符串或者 "anonymous",这样就可以跨域导出图片信息,也就是画图了;
这边MDN上就介绍了这个启用了 CORS 的图片;

最后一点呢,就是,如果这些跨域图片都是自己能够操作服务器开启CORS的当然是最好的,万一没有这个权限,或者操纵的图片对面直接设置了防盗链,前端在浏览器里面可就真的没办法了·····

上一篇下一篇

猜你喜欢

热点阅读