对象HTMLImageElement不能在Internet Explorer中“保存为”图像

时间:2016-01-06 21:35:32

标签: internet-explorer d3.js svg png

我尝试:使用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图像的任何想法? 谢谢。

2 个答案:

答案 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();
   }
};