如何将SVG节点转换为PNG并将其下载到用户?

时间:2013-11-26 03:24:25

标签: javascript canvas svg drawimage save-as

我有一个使用svg构建条形图的应用程序,我想将PNG图像下载给用户。我正在使用FileSaver.js和canvas-to-blob.min.js polyfills来获得对canvas.toBlob()和window.saveAs()的支持。

以下是附加到下载按钮的代码片段:

$('#download-button').on('click', function(e) {
    e.preventDefault();
    var chart = $('#bar-chart')
        .attr('xmlns', 'http://www.w3.org/2000/svg');
    var width = chart.width();
    var height = chart.height();
    var data = new XMLSerializer().serializeToString(chart.get(0));
    var svg = new Blob([data], { type: "image/svg+xml;charset=utf-8" });
    var url = URL.createObjectURL(svg);

    var img = $('<img />')
        .width(width)
        .height(height)
        .on('load', function() {
            var canvas = document.createElement('canvas');
            canvas.width = width;
            canvas.height = height;
            var ctx = canvas.getContext('2d');
            ctx.drawImage(img.get(0), 0, 0);
            canvas.toBlob(function(blob) {
                saveAs(blob, "test.png");
            });
        });
    img.attr('src', url);
});

它为SVG图像提取XML,将其包装在blob中,并为blob创建和对象URL。然后它创建一个图像对象并将其src设置为对象URL。然后,load事件处理程序创建一个画布,并使用drawImage()将图像渲染到画布上。最后,它将图像数据提取到第二个blob,并使用saveAs()将其下载为“test.png”。

一切似乎都有效,但下载的PNG文件没有整个图像 - 只是左上角的一部分。在SVG完全呈现之前,浏览器是否可以触发“加载”事件?或者我在这里错过了什么?

Here is a jsFiddle demonstrating the problem.

1 个答案:

答案 0 :(得分:3)

(移动评论回答所以问题可以关闭:)

SVG元素的100%宽度被解释为100个像素。如果你使用console.log宽度/高度,你可以看到这个。

设置绝对宽度是解决问题的一种方法。