我尝试:使用D3创建一个SVG元素,单击一个按钮将其转换为使用CANVAS的图像,因此可以右键单击并“保存为”图像。
问题:Internet Explorer将[object HTMLImageElement]对象看作“image”,因此当我右键单击它时,它不会提示“将图像另存为...”选项。在Chrome和Firefox中,它可以正常工作。
我有以下HTML代码:
<input type="button" id="toPngBtn" value="Save" /><br />
<div id="myDiv"></div>
<div id="exportDiv"></div>
以下javascript代码:
//Make an SVG Container
var svgContainer = d3.select("#myDiv").append("svg")
.attr("id", "myCircle")
.attr("width", 60)
.attr("height", 60);
//Draw the Circle
var circle = svgContainer.append("circle")
.attr("cx", 30)
.attr("cy", 30)
.attr("r", 20);
// Save button to
d3.select("#toPngBtn").on("click", function () {
var svg = document.getElementById('myCircle');
var xml = new XMLSerializer().serializeToString(svg);
var data = "data:image/svg+xml;base64," + btoa(xml);
var image = new Image;
image.src = data;
var imgWidth = image.width;
var imgHeigth = image.height;
var exportDiv = document.getElementById('exportDiv');
exportDiv.innerHTML = '<canvas id="exportCanvas" width="' + imgWidth + '" height="' + imgHeigth + '"></canvas>';
var canvas = document.querySelector("canvas"),
context = canvas.getContext("2d");
canvas.innerHTML = image;
image.onload = function () {
context.drawImage(image, 0, 0);
};
});
所以我做的是以下内容:当页面加载时,我使用D3.js绘制一个圆圈。如果单击“toPngBtn”按钮,那么我将获取svg元素,序列化它,创建一个新的Image()对象并将blob附加到源。我得到SVG的尺寸并创建一个相同大小的新CANVAS并将其附加到div。我将画布的innerHTML设置为新创建的图像,并且在加载图像时,我告诉上下文绘制图像。
好的部分是图像出现在页面上。不好的是,在Internet Explorer中,我无法右键单击图像并保存。适用于Chrome和Firefox。
问题:是否有解决方法?我试着用
...
image.onload = function () {
context.drawImage(image, 0, 0);
var a = document.createElement("a");
a.download = "svg-graph.png";
a.href = canvas.toDataURL("image/png");
a.click();
};
...
提示文件下载,但是Internet Explorer再也不允许使用CORS,所以它不起作用...有关如何从IE中下载SVG图像的任何想法? 谢谢。
答案 0 :(得分:3)
将svg图像绘制到画布上确实污染了IE中的画布&lt;边缘(以及最新的Safari,如果正在绘制的svg中有<foreignObject>
),出于安全原因。
因此,当您右键单击绘制的画布时,您将无法再访问save image as...
功能。
但是,在这些浏览器中,您只需右键单击原始svg元素,然后选择save image as...
=&gt; yourFile.png
。
所以解决方案是首先尝试在画布上渲染svg,然后通过在try-catch块中调用其toDataURL()
方法来check if it was tainted,或者进行一些UA字符串欺骗和直接向用户发送一些通知,右键单击图像并自行完成...
请注意,即使画布受到污染,它也与您的案例中的跨源资源无关。
答案 1 :(得分:1)
Internet Explorer不支持锚标记的download
属性。
因此,对于Internet Explorer,您可以尝试以下代码
window.navigator.msSaveBlob(canvas.msToBlob(), "svg-graph.png");
已完成的代码:
function isIE() {
var userAgent = window.navigator.userAgent;
return userAgent.indexOf("MSIE ") > -1 || userAgent.indexOf("Trident/") > -1;
}
image.onload = function () {
context.drawImage(image, 0, 0);
if(isIE()){
window.navigator.msSaveBlob(canvas.msToBlob(), "svg-graph.png");
} else{
var a = document.createElement("a");
a.download = "svg-graph.png";
a.href = canvas.toDataURL("image/png");
a.click();
}
};