在浏览器中将svg转换为png图像(跨浏览器,包括IE)

4
我正在使用Highcharts,并且需要将页面上的所有图表转换为图片,以便我可以将其发送到服务器,然后将其合并到包含某些表格和透视网格的主导出Excel中。 这是我目前的代码。
var svg = Highcharts.getSVG(charts);
img = new Image();
img.src = "data:image/svg+xml," + encodeURIComponent(svg);
mycanvas = document.createElement('canvas');
mycanvas.width = 1000
mycanvas.height = 1000
ctx = mycanvas.getContext("2d");
ctx.drawImage(img, 0, 0);
$("body").append("<image src='" + mycanvas.toDataURL("image/png") + "'/>");
$.ajax({
    type: "POST",
    url: '@Url.Action("getfile")',
    data: JSON.stringify({ file: mycanvas.toDataURL("image/png").replace("data:image/png;base64,", "") }),
    contentType: 'application/json; charset=utf-8'
});

这是我测试从客户端正确获取数据的C#代码(我只是将base64字符串写入文件)。Firefox和Chrome可以正确地写入图像,而IE只会给我一个黑色的图像。
public void getfile(string file)
{
    System.IO.File.WriteAllBytes(@"c:\yourfile.png", Convert.FromBase64String(file));
}

你可以在这里找到完整的代码 http://jsfiddle.net/gd7bB/2291/

图像在 Firefox 和 Chrome 中似乎生成得不错,但在 IE 中却不能正常显示(我只能看到黑色的图像)。我正在使用一个画布,从我搜集到的信息来看,IE 是支持 IE9 对 HTML5 画布标签的支持

如果你能帮我找出问题所在,或者指引我更好的解决方案,我将非常感激。

1个回答

3

https://msdn.microsoft.com/fr-fr/library/ff975241(v=vs.85).aspx所述,IE9似乎确实支持canvas元素。

以下用于toDataURL的样本/测试代码在我的IE11上运行良好:http://samples.msdn.microsoft.com/Workshop/samples/canvas/todataurl.html

您提供的fiddle在IE11中不起作用。查看控制台错误,发现您不能在图像完成呈现之前调用drawImage。IE抛出了“调用不受支持的方法或方法属性”的错误。

添加setTimeout允许IE呈现动态图像并绕过此错误。

但这会导致一个问题:

Security Error

因为似乎IE由于某些“跨域”问题已经污染了画布。

SecurityError
The img or video element is not of the same origin or domain
as the document that owns the canvas element. Versions earlier
than Internet Explorer 10 use SECURITY_ERR.

由于安全原因,IE似乎会污染所有填充SVG的图像 - SVG tained canvas IE security error toDataURL

我使用canvg实现了一个可行的版本,它将SVG文件转换为画布指令 - https://github.com/gabelerner/canvg

解决方案可以概括如下:

var svg = Highcharts.getSVG(charts);
var mycanvas = document.createElement('canvas');
canvg(mycanvas, svg)
console.log(mycanvas.toDataURL("image/png"))

请检查这个 fiddle http://jsfiddle.net/6bxqbaeb/1/,它可以在 IE11 中正常工作。


我尝试只保留来自Ajax的调用,但仍然是相同的结果。你给我的链接在我的IE9中也可以工作,所以我想我会尝试查看那里的代码,看看我做了什么不同的地方。谢谢,我会让你知道的。 - Liviu Boboia
我添加了一个建议的解决方案。我认为没有简单的解决方案,因为IE处理SVG和跨域策略的方式。如果canvg支持您的一组SVG元素,则我认为它将适用于您的问题。 - Jerome WAGNER
非常感谢,这个可行。我的结论是IE9不支持类型为svg的图像源(即:data:image/svg+xml)。 - Liviu Boboia

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接