对象 HTMLImageElement 不能是 Internet Explorer 中的 "saved as" 图片

object HTMLImageElement cannot be "saved as" image in Internet Explorer

我尝试:使用 D3 创建一个 SVG 元素,单击一个按钮将其转换为使用 CANVAS 的图像,因此可以右键单击并 "saved as" 图像。

问题:[object HTMLImageElement] 对象在 Internet Explorer 中不可见 "image" 所以当我右键单击它时,它不会提示 "Save image as..."选项。在 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。我将 canvas 的 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 图像的任何想法? 谢谢。

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

为了安全起见,将 svg 图像绘制到 canvas 确实污染了 IE < Edge 中的 canvas(如果 <foreignObject> 在正在绘制的 svg 中,则在最新的 Safari 中原因。

因此,当您右键单击绘制的 canvas 时,您将无法再访问 save image as... 功能。

但是,在这些浏览器中,您只需右键单击原始 svg 元素并选择 save image as... => yourFile.png

所以解决方案是首先尝试在 canvas 上渲染 svg,然后 check if it was tainted 通过在 try-catch 块中调用它的 toDataURL() 方法,或者做一些 UA-string 欺骗并直接向用户发送一些通知,让用户右键单击图像并自行完成...

请注意,即使 canvas 被污染,它与您的情况下的 cross-origin-resources 无关。