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

标签 javascript canvas svg drawimage save-as

我有一个使用 svg 构建条形图的应用程序,我想为用户下载 PNG 图像。我正在使用 FileSaver.js 和 canvas-to-blob.min.js polyfill 来获得对 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。然后加载事件处理程序创建一个 Canvas 并使用 drawImage() 将图像渲染到 Canvas 上。最后,它将图像数据提取到第二个 blob,并使用 saveAs() 将其下载为“test.png”。

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

Here is a jsFiddle demonstrating the problem.

最佳答案

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

SVG 元素的 100% 宽度被解释为 100 像素。如果您控制台记录宽度/高度,您可以看到这一点。

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

关于javascript - 如何将 SVG 节点转换为 PNG 并将其下载给用户?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20207924/

相关文章:

javascript - 如何将 API 响应作为 JSON 对象发送给客户端?

css - SVG 动画结合@keyframes

javascript - IE Canvas dataURI 安全错误

javascript - 在 threejs 中加载到 Material 上的 svg 的每个 <g> 标签上的鼠标事件

javascript - 从子 javascript 更改父级中的变量值

javascript - WebStorm 无法识别 Mocha describe() 和 it()

javascript - dimple js测量轴值

javascript - 如何删除 JavaScript Canvas 渲染上下文的状态堆栈?

javascript - 鼠标单击在 html5 的柱形图中不起作用

html - Chrome 在 <img> 中加载 SVG 时发出警告