Internet explorer 在IE中将动态SVG转换为可下载的PNG
目标-使用客户端: 将动态SVG图形(使用d3js创建)转换为可下载的PNG图像,并使用Internet Explorer工作 完成: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 =
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”