canvas toDataURL 与 drawImage 注意事项

一、drawImage 需要等图片加载完成

    const LoadImage = (url) => {
      var img = new Image();
      img.src = url;
      return new Promise((resolve, reject) => {
        img.onload = () => {
          resolve(img); //成功
        };
        img.onerror = () => {
          reject(); //失败
        };
      });
    }

完成这个步骤,图片就可以正确的绘制到画布上了。

二、toDataURL 报错

Failed to execute 'toDataURL' on 'HTMLCanvasElement'

image.png

在加载img时设置 crossorigin 为 anonymous 即可以解决

    const LoadImage = (url) => {
      var img = new Image();

      img.setAttribute("crossorigin", "anonymous");  // 在加载img时设置 crossorigin 

      img.src = url;
      return new Promise((resolve, reject) => {
        img.onload = () => {
          resolve(img); //成功
        };
        img.onerror = () => {
          reject(); //失败
        };
      });
    }

三、报跨越问题

当设置了 crossorigin 为 anonymous 后,可能会出现报跨越问题。

image.png
现象:
  1. 本地图片。(正常)
  2. 线上图片,未信任前端域名。(报跨域)
  3. 线上图片,信任了前端域名。(有可能,还是会报跨越)
原因+方案:

现象1:不多说。
现象2:原因不多说。方案就是让提供图片的服务信任前端域名即可解决。
现象3:这个按正常来说,图片的服务信任了前端域名,即不再回报错。

image.png
image.png

四、总结

  1. 仅仅在canvas上绘制图片,只需要图片加载完成后即可以绘制。
  2. 如果要把绘制的canvas图toDataURL导出:
    同域图片:不需要做什么。
    跨越图片:加载图片时需要 设置 crossorigin 为 anonymous。需要注意缓存问题。
完整调试代码
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style>
    * {
      margin: 0;
      padding: 0;
    }

    img {
      width: 50%;
      max-width: 50%;
    }
  </style>
</head>

<body>
  
  <h2>img 显示 图片</h2>
  <p>
    <img src="https://cdn2.jianshu.io/assets/web/nav-logo-4c7bbafe27adc892f3046e6978459bac.png">
    <!-- 自行改图片地址 -->
  </p>

  <h2>canvas 画图</h2>
  <canvas id="canvas" width="750" height="1134" style="width: 100%; height:100%"></canvas>


  <script>

   const coverUrl = 'https://cdn2.jianshu.io/assets/web/nav-logo-4c7bbafe27adc892f3046e6978459bac.png?id=x';  //自行改图片地址
    const DrawCanvas = {
      async drawCover() {
        this.canvas = document.getElementById('canvas');
        this.context = this.canvas.getContext("2d");

       
        const coverUrlData = await LoadImage(coverUrl).catch(error => {
          return error;
        });
        coverUrlData && this.context.drawImage(
          coverUrlData,
          0,
          0,
          coverUrlData.width,
          coverUrlData.height,
          0,
          0,
          750,
          1134
        );

        const base64ImageData = this.canvas.toDataURL("image/jpeg");
        console.log(base64ImageData)
      }
    }
    const LoadImage = (url) => {
      var img = new Image();

      img.setAttribute("crossorigin", "anonymous");

      img.src = url;
      return new Promise((resolve, reject) => {
        img.onload = () => {
          resolve(img); //成功
        };
        img.onerror = () => {
          reject(); //失败
        };
      });
    }

    DrawCanvas.drawCover()
  </script>
</body>

</html>
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容