【问题标题】:Save svg image rendered by a javascript to local disk as .png file将 javascript 呈现的 svg 图像保存到本地磁盘为 .png 文件
【发布时间】:2012-01-12 21:00:15
【问题描述】:

我是 SVG 新手,不是 JavaScript 的高级用户。我有一个由 javascript 动态呈现 svg 内容的网页。在 Internet Explorer 中,当我右键单击 svg 内容时,我会看到“将图片另存为”选项,我可以将内容保存为 png 或 svg。

我如何通过一个按钮以编程方式做到这一点,并允许用户将 png 格式的内容保存到他们的机器上。

【问题讨论】:

  • 由于浏览器的安全性,这应该是不可能的。想想如果您可以在未经用户同意的情况下使用 JavaScript 将数据写入用户机器的危险。
  • 有一个类似的问题。看到这个链接stackoverflow.com/questions/2483919/…
  • 之前有人问过类似的问题。看到这个stackoverflow.com/questions/2483919/…
  • 感谢您的回复 Ranhiru Cooray,但未经用户同意,我不会编写数据。单击按钮将打开一个对话框,允许用户选择他们想要保存文件的位置。与点击“图片另存为”时 IE 完全相同。
  • lya,感谢您的回复。我已经浏览了链接 stackoverflow.com/questions/2483919/… 但它只是做同样的事情,比如右键单击链接,然后执行“另存为”。

标签: c# javascript .net


【解决方案1】:

根据我的研究,如果不将 svg 内容发送到您的服务器并让它返回数据以另存为文件下载,则无法做到这一点。

但是,即使这也很难通过单个 AJAX 样式的请求来实现,而且解决方案非常复杂。其他人已经链接到其他解释这一点的帖子,但我已经经历了相同的答案,但没有一个能很好地解释它。

以下是对我有用的步骤:

  1. 使用 JavaScript 序列化 SVG 内容。

    var svgString = new XMLSerializer().serializeToString(svgElement);

  2. 创建一个隐藏的iframe,其src 是提交网址。给它一个id
  3. 创建一个隐藏的input。将此inputvalue 设置为序列化的SVG 内容。
  4. 创建一个表单,其目标是给iframeid,其action 是提交网址。将input 放在form 中。
  5. 提交form
  6. 在您的服务器上,使用任何可用的工具(我不使用 .NET,所以您自己在这里...)将 SVG 文档转换为 PNG。将 PNG 内容发送回客户端,确保使用标头:

    Content-Type:image/png

    Content-Disposition:attachment; filename=mypng.png

浏览器应该在返回的内容上启动文件下载,虽然这取决于浏览器并且我不确定,但有些浏览器可能会选择在新选项卡中打开图像而不是打开文件下载对话框。

这是一个(不完美的)函数,它将完成 AJAX 工作(使用 JQuery,但您应该明白这一点)。 data 是序列化的 SVG:

function ajaxFileDownload(url, data) {
    var iframeId = "uniqueIFrameId";     // Change this to fit your code
    var iframe = $("#" + iframeId); 

    // Remove old iframe if there
    if(iframe) { 
        iframe.remove(); 
    }

    // Create new iframe 
    iframe = $('<iframe src=""' + url + '"" name="' + iframeId + '" id="' + iframeId + '"></iframe>')
        .appendTo(document.body)
        .hide(); 

    // Create input
    var input = '<input type="hidden" name="data" value="' + encodeURIComponent(data) + '" />'; 

    // Create form to send request 
    $('<form action="' + url + '" method="' + 'POST' + '" target="' + iframeId + '">' + input + '</form>')
        .appendTo(document.body)
        .submit()
        .remove();
}

请注意,此 URL 对 SVG 内容进行编码,因此在转换为 PNG 之前,您必须在服务器上对其进行解码。

另外请注意,如果您在外部样式表中为 SVG 定义了样式,它们将不会被序列化。出于这个原因,我决定将元素上的所有样式内联为presentation attributes

我希望这会有所帮助。

【讨论】:

  • 谢谢托尼。它对我想要实现的目标没有帮助,但它帮助我朝着正确的方向前进!
猜你喜欢
  • 2012-01-12
  • 2014-11-05
  • 2016-11-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-03-26
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多