目标 - 使用客户端:
将动态SVG绘图(使用d3js 创建的)转换为可下载的PNG图像,并使用Internet Explorer进行工作。
完成:
在Chrome中实现,没问题。一旦我有了PNG DataURI,就可以很容易地将其转换为可下载的PNG blob。
不幸的是,在IE中运行相同的代码会产生SecurityException,当我尝试将画布转换为PNG DataURI( canvas.toDataURL )时,它会失败。
显然这是一个活跃的IE BUG,我在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);
更新
测试了Canvg对2d上下文“ drawSvg(...)”的扩展,它绘制在画布上。这在canvas元素上调用toDataURL时克服了SecurityException,但是draw函数对于文本呈现和放置来说不够准确。所以我仍然需要一个解决方案。
参见示例屏幕截图,left correct rending using native drawImage and right the incorrect rendering using Canvg's drawSvg
使用Canvg的代码 - 注意:您需要引用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();