Internet explorer 在IE中将动态SVG转换为可下载的PNG

Internet explorer 在IE中将动态SVG转换为可下载的PNG,internet-explorer,canvas,svg,todataurl,Internet Explorer,Canvas,Svg,Todataurl,目标-使用客户端: 将动态SVG图形(使用d3js创建)转换为可下载的PNG图像,并使用Internet Explorer工作 完成: var rawSvg = new XMLSerializer().serializeToString(svgElement); var img3 = new Image(); document.body.appendChild(img3); var canv = document.createElement("canvas"); var canv_ctx =

目标-使用客户端:

将动态SVG图形(使用d3js创建)转换为可下载的PNG图像,并使用Internet Explorer工作

完成:

var rawSvg = new XMLSerializer().serializeToString(svgElement);

var img3 = new Image();
document.body.appendChild(img3);
var canv = document.createElement("canvas");
var canv_ctx = canv.getContext("2d");

img3.onload = function () {
   //-- Image has loaded using the native data:image/svg+xml 
   canv_ctx.drawImage(this, 0, 0);

   //-- IE Will throw a Security Exception here...
   console.log(canv.toDataURL("image/png")); 
};

img3.src = "data:image/svg+xml;base64," + btoa(rawSvg);
//-- Or utf8
//img3.src = "data:image/svg+xml;charset=utf8," + encodeURIComponent(rawSvg);
在Chrome中实现,没有问题。一旦我有了PNG数据URI,它就可以很容易地转换为可下载的PNG blob

不幸的是,在IE中运行相同的代码会产生SecurityException,当我尝试将画布转换为PNG数据URI(canvas.toDataURL)时,它失败了

显然,这是一个活跃的问题,我在StackExchange上发现其他人也有同样的问题。我相信这与应用于来自其他域(并在画布中绘制)的图像的CORS限制有关,但我的SVG源于本地页面

思想

不知道原因是否与我为IMG元素呈现的svg图形生成初始DataURI(data:image/svg+xml)的方式有关

我尝试了两种方法来生成image/svg+xml,base64和charset=utf8,但它们没有解决遇到的问题。所以想知道它是否是SVG的内容,目前SVG图形中没有图像

参考代码:

var rawSvg = new XMLSerializer().serializeToString(svgElement);

var img3 = new Image();
document.body.appendChild(img3);
var canv = document.createElement("canvas");
var canv_ctx = canv.getContext("2d");

img3.onload = function () {
   //-- Image has loaded using the native data:image/svg+xml 
   canv_ctx.drawImage(this, 0, 0);

   //-- IE Will throw a Security Exception here...
   console.log(canv.toDataURL("image/png")); 
};

img3.src = "data:image/svg+xml;base64," + btoa(rawSvg);
//-- Or utf8
//img3.src = "data:image/svg+xml;charset=utf8," + encodeURIComponent(rawSvg);
更新:

var rawSvg = new XMLSerializer().serializeToString(svgElement);

var img3 = new Image();
document.body.appendChild(img3);
var canv = document.createElement("canvas");
var canv_ctx = canv.getContext("2d");

img3.onload = function () {
   //-- Image has loaded using the native data:image/svg+xml 
   canv_ctx.drawImage(this, 0, 0);

   //-- IE Will throw a Security Exception here...
   console.log(canv.toDataURL("image/png")); 
};

img3.src = "data:image/svg+xml;base64," + btoa(rawSvg);
//-- Or utf8
//img3.src = "data:image/svg+xml;charset=utf8," + encodeURIComponent(rawSvg);
测试了Canvg对二维上下文“drawSvg(…)”的扩展,该扩展将绘制到画布上。这克服了在canvas元素上调用toDataURL时出现的SecurityException问题,但是draw函数对于文本呈现和放置来说不够精确。所以我仍然需要一个解决方案

参见示例屏幕截图

使用Canvg-NB的代码:您需要引用JS

var canvas = document.createElement("canvas"),
    cctx = canvas.getContext("2d");
var rawSvg = new XMLSerializer().serializeToString(svgClone.node());
canvas.width = svgWidth;
canvas.height = svgHeight;
//cctx.drawImage(this, 0, 0);
//-- Use Canvg's extension to canvasContext
cctx.drawSvg(rawSvg);
//-- This Works on IE - not accurate though
var dataURL = canvas.toDataURL();

根据d3创建的SVG的复杂性,您可以使用它将SVG转换为画布绘图命令。然后跨域限制不再适用。是的,这是一个应用于IE“png”的安全限制。请注意,当您绘制包含
元素的svg时,同样的限制也适用于最新的safari版本。Ps:这个限制在Edge上不再适用,所以我认为你链接到的bug(这是一个功能,顺便说一句,不是bug)永远不会被修复。@markE我刚刚在他们的JS fiddle游乐场上做了一个测试,如果我在canvas元素上使用他们的drawimage,那么我可以在canvas上生成一个DataURI实例。太好了!谢谢,一旦我验证了它在我的机器上的有效性,我会发布一些代码。@Kaido干杯,我不知道这在Edge上有效。根据MarkE的建议,我已经使用canvg在画布上绘制了一个快速测试,这似乎允许导出到PNG。@Nicholas,恐怕我们提供了您仅有的3个解决方案。修复canvg库,将自己的svg写入画布绘图命令库,要求用户右键单击svg“另存为…”“png”