zoukankan      html  css  js  c++  java
  • canvas绘图之跨域报错问题

      首先说下需求,一张海报图片于一张前端生成的二维码绘制出一幅海报来,二维码生成的本质就是一张canvas,此时我们可以利用toDataURL方法将这张二维码转成base64 

    接着创建一个img标签  让其src等于这个base64,接着海报和二维码就放在了两张图片中了,到了这步大家是不是觉得大功告成了可以美滋滋的画图了,岂不知一波坑就此袭来了~~~

      第一个错如下。。。。

      Failed to execute 'toDataURL' on 'HTMLCanvasElement': Tainted canvases may not be exported.

      什么意思呢  其实由于同源策略的原因canvas被污染了,无法使用toDataURL去导出canvas的数据 

      此时有的小伙伴可能想到了,去设置跨域属性img.setAttribute("crossOrigin",'anonymous');这个属性吧,然后兴高采烈的去尝试发现还不行~~~~

     

    所以这时候就要找你服务端小哥哥了,问下你们服务器是否设置被允许访问了

    到了这里大家肯定觉得终于行了,然后一试。。。。满屏红的跨域报错信息又出来了。。。。此时来自一枚程序员无声的呐喊挣扎中~~~

      多次挣扎后终于找到解决方案 src属性后面拼接一个时间戳就可以了!!!

    内心反复不相信,多次尝试后还真是这么狗就能出来~~~

    function drawRoundRectPath(cxt, width, height, radius) {
      cxt.beginPath(0);
      //从右下角顺时针绘制,弧度从0到1/2PI  
      cxt.arc(width - radius, height - radius, radius, 0, Math.PI / 2);
      //矩形下边线  
      cxt.lineTo(radius, height);
      //左下角圆弧,弧度从1/2PI到PI  
      cxt.arc(radius, height - radius, radius, Math.PI / 2, Math.PI);
      //矩形左边线  
      cxt.lineTo(0, radius);
      //左上角圆弧,弧度从PI到3/2PI  
      cxt.arc(radius, radius, radius, Math.PI, Math.PI * 3 / 2);
      //上边线  
      cxt.lineTo(width - radius, 0);
      //右上角圆弧  
      cxt.arc(width - radius, radius, radius, Math.PI * 3 / 2, Math.PI * 2);
      //右边线  
      cxt.lineTo(width, height - radius);
      cxt.closePath();
    }
    
    function fillRoundRect(cxt, x, y, width, height, radius, fillColor) {
      //圆的直径必然要小于矩形的宽高          
      if (2 * radius > width || 2 * radius > height) { return false; }
      cxt.save();
      cxt.translate(x, y);
      //绘制圆角矩形的各个边  
      drawRoundRectPath(cxt, width, height, radius);
      cxt.fillStyle = fillColor || "#000"; //若是给定了值就用给定的值否则给予默认值  
      cxt.fill();
      cxt.restore();
    }
    
    
    const canvasQr = (posterCanvas, qrCanvas, poster, qrCodeCanvas, setImgW) => {//下载图片地址和图片名
      return new Promise((resolve, reject) => {
        try {
          const posterCtx = posterCanvas.getContext('2d');
          const qrCtx = qrCanvas.getContext('2d');
          const img1: any = new Image();
          const img2: any = new Image();
          const newimg1: any = new Image();
          img1.setAttribute('crossorigin', 'anonymous')
          img1.src = poster + "?" + new Date().getTime();
          img1.onload = () => {
            setImgW({
               img1.width,
              height: img1.height
            })
            qrCtx.drawImage(img1, 0, 0, img1.width, img1.height);
            newimg1.src = qrCanvas.toDataURL();
            newimg1.onload = () => {
              posterCtx.drawImage(qrCanvas, 0, 0, img1.width, img1.height);
              //带圆角的白色矩形
              fillRoundRect(posterCtx, img1.width - (img1.width / 3) - 18, img1.height - (img1.width / 3) - 40, (img1.width / 3), (img1.width / 3), 20, '#fff');
              img2.src = qrCodeCanvas.toDataURL();
              img2.onload = () => {
                posterCtx.drawImage(img2, img1.width - (img1.width / 3) - 8, img1.height - (img1.width / 3) - 30, (img1.width / 3) - 20, (img1.width / 3) - 20);
                resolve(posterCanvas.toDataURL())
              };
            }
          }
        } catch (error) {
          reject("error")
        }
    
      })
    
    }
    
    export default canvasQr

      

  • 相关阅读:
    Java用freemarker导出word
    springMVC集成缓存框架Ehcache
    java爬虫入门--用jsoup爬取汽车之家的新闻
    基于全注解的SpringMVC+Spring4.2+hibernate4.3框架搭建
    spring aop实现日志收集
    ELK + kafka 日志方案
    大数据挖掘方案
    elasticsearch例子(crud + 分页)
    分类(category)是门学问
    英语单词辨异 —— 容易理解错的单词
  • 原文地址:https://www.cnblogs.com/cq1715584439/p/12753434.html
Copyright © 2011-2022 走看看