【问题标题】:object HTMLImageElement cannot be "saved as" image in Internet Explorer对象 HTMLImageElement 不能在 Internet Explorer 中“另存为”图像
【发布时间】:2016-01-07 15:16:07
【问题描述】:

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

问题:Internet Explorer 看不到 [object HTMLImageElement] 对象作为“图像”,因此当我右键单击它时,它不会提示“将图像另存为...”选项。在 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 制作图像可下载的任何想法? 谢谢。

【问题讨论】:

    标签: internet-explorer d3.js svg png


    【解决方案1】:

    出于安全原因,将 svg 图像绘制到画布上确实会污染 IE <foreignObject>,则在最新的 Safari 中)。

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

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

    所以解决方案是首先尝试在画布上渲染 svg,然后通过在 try-catch 块中调用其 toDataURL() 方法来 check if it was tainted,或者进行一些 UA 字符串欺骗并直接发送一些通知让用户右键单击图像并自己做...

    请注意,即使画布被污染,在您的情况下也与跨域资源无关。

    【讨论】:

    • 您知道为什么 IE 11 用户会报告无法通过右键单击 svg 元素来“将图片另存为”选项吗?该选项似乎适用于一个用户,但不是另一个用户,即使两者具有相同的 IE 版本。
    • @Dave,不,我不知道,真的很抱歉,如果您发现我会很高兴听到原因。也许是一些插件或杀毒软件?
    【解决方案2】:

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

    【讨论】:

    • 我很想支持它,因为我不知道 IE 的 navigator.msSaveBlob 方法,但是如果画布被污染(当您在 IE
    • 非常感谢。这是我们一直存在的问题的解决方案。这其实就是将 D3.js Graph 保存为 PNG 的解决方案。
    猜你喜欢
    • 1970-01-01
    • 2013-03-20
    • 2011-03-04
    • 1970-01-01
    • 1970-01-01
    • 2010-11-04
    • 1970-01-01
    • 1970-01-01
    • 2020-10-02
    相关资源
    最近更新 更多