html2canvas在SVG上下载带有背景图片的图片

时间:2018-12-12 22:16:34

标签: javascript svg html2canvas

您好,html2canvas和SVG大师也许可以为我提供帮助,我试图从SVG下载图像,用户在SVG区域上设置了图像,但是当我使用html2canvas生成图像时,背景图像显得奇怪并下载了生成的文件,我得到一个错误: “未捕获(承诺)DOMException:无法在以下对象上执行'toDataURL' 'HTMLCanvasElement':受污染的画布可能无法导出。“

我举了一个例子来更好地理解: 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");
  });

谢谢。

1 个答案:

答案 0 :(得分:1)

我不太了解您的问题。我想您在这里问了两件事(图像看起来很奇怪,由于画布变脏而无法下载)。

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

对于第二个(变色画布),您正在处理一个安全问题:

Allowing cross-origin use of images and canvas

上面的链接深入说明了您面临的问题。

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

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

Working version of your fiddle (download canvas is possible)

这是受影响的代码,以及我替换掉的代码以使其正常工作(被截断):

/* ... */
            <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中的图像从与页面其余部分相同的位置开始提供。如果出于某些原因/用例需要获取构图的外来图像,则这些图像应由后端代理。

无论如何,我已经调整了一些小提琴,现在可以在Chrome,Firefox和Safari中使用它了。 Edge无法正常工作(但是考虑到您最初的实现方式,我想您还没有尝试过)。

Upgraded jsFiddle version

此版本突出了您应该do to replace the image in your SVG的内容。

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

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函数。这将“预热”“真实”调用的过程。

我的小提琴只是为了证明这一壮举是可以实现的,但是尝试使用后端代理方法或其他设计来解决您的问题。