我不太明白你的问题。我想你在这里问两件事(图像看起来很奇怪,由于画布被污染,无法下载)。
对于第一个问题,您应该澄清您真正要问的问题(奇怪是什么意思?您想达到什么目的?...)
对于第二个(污染的画布),您正在处理安全问题:
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 函数。这将为“真正的”调用“预热”过程。
我提琴的目的只是为了证明可以完成这项壮举,但请尝试使用后端代理方法或不同的设计来解决您的问题。