javascript - html2canvas 下载带有 SVG 背景图像的图像

标签 javascript svg html2canvas

嗨,html2canvas 和 SVG 大师也许你可以帮助我,我正在尝试从 SVG 下载图像,用户在 SVG 区域上设置图像,但是当我使用 html2canvas 生成图像时,背景图像看起来很奇怪,需要下载生成的文件,我收到错误: “未捕获( promise 中)DOMException:无法执行‘toDataURL’ “HTMLCanvasElement”:受污染的 Canvas 可能无法导出。”

我举了一个例子来更好地理解: http://jsfiddle.net/equerol/sodofkcs/5711/

  html2canvas(document.getElementById("svgContainer"), {
    logging: true,
    allowTaint: true,
  }).then(function(canvas) {
    document.body.appendChild(canvas);
    var myImage = canvas.toDataURL("image/png");
    downloadURI("data:" + myImage, "yourImage.png");
  });

谢谢。

最佳答案

我不太明白你的问题。我认为您在这里问两件事(图像看起来很奇怪,由于 Canvas 受污染而无法下载)。

对于第一个问题,您应该澄清您真正要问的内容(奇怪是什么意思?您想实现什么目标?...)

对于第二个(受污染的 Canvas ),您正在处理安全问题:

Allowing cross-origin use of images and canvas

上面的链接深入解释了您面临的问题。

您应该尝试使用链接中建议的方法之一。

通过在 Canvas 中使用嵌入的图像数据 URI,我可以轻松克服安全问题,使其不再受到污染。我基本上用 dataURI 替换了您的外部图像 URL。 请尝试找到适合您问题的更好解决方案。

Working version of your fiddle (download canvas is possible)

以下是受影响的代码以及我为使其正常工作而替换的代码(已 chop ):

/* ... */
            <g id="svgPoly4" clip-path="url(#d)" class="droppable">
              <image width="500" height="500" xlink:href="data:image/png;base64,iVBORw0KGgoAAAA....ggg=="></image>
        </g>
/* ... */

更新 1//2019-01-08

抱歉,在原来的答案中我应该更清楚地了解您面临的安全问题。

基本上,您正在尝试获取在 SVG 合成中重新格式化/重新设计的外国图像的屏幕截图。这意味着恶意实体可以使用此技术劫持用户的敏感信息(图像),以防浏览器没有阻止。

要解决您的问题,您真正应该做的就是提供与页面其余部分同源的 SVG 中嵌入的图像。如果由于某种原因/用例您需要获取外部图像用于合成,这些图像应由您的后端代理。

无论如何,我对你的 fiddle 做了一些调整,现在它可以在 Chrome、Firefox 和 Safari 中使用。 Edge 无法工作(但鉴于您最初的实现,我猜您还没有尝试过)。

Upgraded jsFiddle version

此版本强调了您应该做什么 do to replace the image in your SVG .

注意:图像之前已上传到允许跨源访问资源的服务器(它添加了 Access-Control-Allow-Origin header )

SVG html 作为模板字符串加载,加载图像时数据 URL 将被替换。

图片已加载:

var downloadedImg = new Image;
downloadedImg.crossOrigin = "Anonymous";
downloadedImg.addEventListener("load", imageReceived, false);
downloadedImg.src = "https://i.imgur.com/szhc74z.png";

模板 SVG html 字符串中的数据 URL 被替换:

var svg = svgTemplate.replace('${imageUrl}', dataUrl);
document.getElementById('rootSvg').innerHTML = svg;

Safari 的其他解决方法:

html2canvas 及其“重新渲染”SVG 的方式似乎存在某种问题。

为了缓解这种情况,一旦将 SVG 添加到文档中,就会调用 html2canvas 函数。这将为“真正的”调用“预热”过程。

我的 fiddle 的目的只是为了证明这一壮举是可以完成的,但是尝试使用后端代理方法或不同的设计来解决您的问题。

关于javascript - html2canvas 下载带有 SVG 背景图像的图像,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53752220/

相关文章:

javascript - Backbone 获取请求是 OPTIONS 方法

javascript - es6 生成器 while(true)

javascript - 如何在 Google map 中正确使用复杂的 SVG 图像路径

javascript - 如何在整个圆圈周围添加描边并在 svg 中动画旋转圆圈?

javascript - HTML2Canvas 不呈现 D3 字体和字体大小

javascript - AngularJS |如何包含拖放列表?

php - 我怎样才能用 JavaScript 编写这个 PHP 代码

javascript - 将 Google Geochart 标记更改为自定义 png 图标

javascript - html2canvas 覆盖 css(字体)

jquery - html2canvas - 安全错误 : The operation is insecure