You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JavaScript向canvas绘制图片失败 导出提示Tainted canvases报错如何解决

报错原因

这个错误是浏览器的Canvas跨域安全限制导致的画布污染:只要Canvas中绘制了未配置跨域许可的资源,浏览器就会将画布标记为只读状态,禁止调用toBlob()、toDataURL()、getImageData()这类导出类接口。

解决方案

按以下步骤修改即可:

  • 加载水印图片前,先给Image对象设置crossOrigin属性为anonymous,该配置必须写在给src赋值之前才会生效
  • 确认你项目的静态资源服务(本地开发服务/线上服务器)已经给assets目录下的图片资源配置了Access-Control-Allow-Origin跨域响应头,允许当前站点域名访问
  • 如果是本地用file://协议直接打开页面调试,跨域配置不会生效,需要用本地HTTP服务启动项目(比如VSCode的Live Server插件)
  • 如果你用到的输入图片file也是跨域来源,同样需要给输入图片的img对象加上crossOrigin配置
修改后的核心代码
// 读取输入文件
const reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = () => {
  // 创建画布、计算水印尺寸和位置
  const canvas = document.createElement("canvas");
  canvas.width = canvasSize.width;
  canvas.height = canvasSize.height;
  var calcW = canvasSize.width/2;
  var calcH = calcW/2.16;
  var calcX = (canvasSize.width - calcW)/2;
  var calcY = (canvasSize.height - calcH)/2;

  // 将输入图片加载到画布
  const img = document.createElement("img");
  // 如果输入图片也为跨域资源,可取消注释下行配置
  // img.crossOrigin = 'anonymous'
  img.src = reader.result;
  img.onload = () => {
    const ctx = canvas.getContext("2d");
    ctx.drawImage(img, 0, 0);

    // 加载并绘制水印图片
    const mark = new Image();
    // 新增跨域配置,必须放在src赋值前
    mark.crossOrigin = 'anonymous';
    mark.src = 'assets/img/compliant.png';
    mark.onload = () => {
      ctx.drawImage(mark, calcX,calcY,calcW,calcH);

      // 转blob并生成访问地址
      canvas.toBlob((canvasBlob) => {
        const newImg = document.createElement("img"),
        url = URL.createObjectURL(canvasBlob);

        newImg.onload = function () {
          // 图片加载完成后销毁对象地址
          URL.revokeObjectURL(url);
        };

        // 展示加水印后的图片
        newImg.src = url;
        window.open(url);
      });
    };
  };
};

内容的提问来源于stack exchange,提问作者Gmanski 156

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.25 01:15:07