图片合成

237 阅读2分钟

需求

现在要做一个扫码移车的图片,图片是通过两张图片合成的,一张是本地背景图片,另外一张是通过服务生成带有个人联系方式的信息的二维码图片,别人通过扫码联系车主移车。

解决方案

canvas

对于涉及到多张图片来绘制,我们最常用的,也最先会想到的就是canvas

<div>
  <canvas id="canvas"></canvas>
</div>
const el = document.getElementById('canvas')
let ctx = el.getContent('2d')
ctx.drawImage(image, 0, 0) // drawImage第二和第三个参数是以左上角为参考点的平移位置

通过以上drawImage的绘制,本地背景图就可以被绘制到id="canvas"的DOM元素上了。

再通过同样的方式改变绘制的坐标就可以绘制居中的个人联系信息二维码图片了。但在做的过程中有个小问题:二维码是通过接口获取的,如果是跨域图片,绘制过程就会报错。

这是因为画布不接收可能带来安全隐患的跨域图片,可能会导致很多安全问题或污染画布。

第一种解决方法是可以启用CORS属性,直接使用连接的资源地址

const imageURL = 'https://cdn.glitch.com/xxx.png'
downloadedImg = new Image()
// 设置跨域属性
downloadedImg.crossOrigin = 'Anonymous'
downloadedImg.src = imageURL

另一种解决方法是先把接口请求到的图片地址通过base64格式转化成了一串本地代码,再传给drawImage方法来绘制。

function getBase64Image () {
  const el = document.getElementById('canvas')
  // toDataURL可以配置图片格式,如'image/png',缺省默认:text/plain;charset=US-ASCII
  let dataUrl = el.toDataURL('image/png') 
}

虽然第一种方式对跨域图片开通了绿色通道,可以任意访问到,有污染画布和安全风险,但第二种方式也会有同样的问题,它仅仅是把图片先包装成了本地图片,其实对于图片本身来说还是相同的资源,只是让canvas没有感知到而已。