如何将svg canvas保存到本地文件系统

dr *_*rry 75 javascript filesystems svg local save

有没有办法让用户在使用浏览器在javascript svg画布上创建矢量图后,将该文件下载到本地文件系统?

SVG对我来说是一个全新的领域,如果我的措辞不准确,请耐心等待.

The*_*Who 64

您可以避免往返服务器.

Base64编码你的SVG xml.

然后生成指向该数据的链接.用户可以右键单击以在本地保存.

// This example was created using Protovis & jQuery
// Base64 provided by http://www.webtoolkit.info/javascript-base64.html
// Modern web browsers have a builtin function to this as well 'btoa'
function encode_as_img_and_link(){
 // Add some critical information
 $("svg").attr({ version: '1.1' , xmlns:"http://www.w3.org/2000/svg"});

 var svg = $("#chart-canvas").html();
 var b64 = Base64.encode(svg); // or use btoa if supported

 // Works in recent Webkit(Chrome)
 $("body").append($("<img src='data:image/svg+xml;base64,\n"+b64+"' alt='file.svg'/>"));

 // Works in Firefox 3.6 and Webit and possibly any browser which supports the data-uri
 $("body").append($("<a href-lang='image/svg+xml' href='data:image/svg+xml;base64,\n"+b64+"' title='file.svg'>Download</a>"));
}
Run Code Online (Sandbox Code Playgroud)

img标签适用于Webkit,该链接适用于Webkit和Firefox,可以在任何支持的浏览器中使用 data-uri

  • 此示例使用http://www.webtoolkit.info/javascript-base64.html中的库 (6认同)
  • 如果文本包含Unicode字符,请使用`btoa(unescape(encodeURIComponent(svg)))` - 不需要库. (5认同)
  • `Base64`来自哪里? (2认同)
  • 使用HTML5,您还可以将"download"属性添加到链接中,这使用户更容易一些.[见这里](http://davidwalsh.name/download-attribute)了解更多信息 (2认同)

Eli*_*rey 18

使用FileSaver.js

saveAs(new Blob([SVG_DATA_HERE], {type:"application/svg+xml"}), "name.svg")
Run Code Online (Sandbox Code Playgroud)


mac*_*13k 18

无需进行base64编码 - 您可以在其中创建包含原始SVG代码的链接.这是一个修改过的函数encode_as_img_and_link()来自The_Who的答案:

function img_and_link() {
  $('body').append(
    $('<a>')
      .attr('href-lang', 'image/svg+xml')
      .attr('href', 'data:image/svg+xml;utf8,' +  unescape($('svg')[0].outerHTML))
      .text('Download')
  );
}
Run Code Online (Sandbox Code Playgroud)


zne*_*eak 15

可能可以使用常规的"保存"浏览器命令,但它不仅会保存SVG画布,而是会保存整个页面.

我相信你最好的选择是使用AJAX并将整个SVG XML数据作为POST数据发送到服务器脚本,并让该脚本只发回带有标题的POST数据Content-Disposition: attachment; filename=yourfile.svg.

(在PHP下,您可以使用file_get_contents('php://input').获取原始POST内容.)


dr *_*rry 11

使用Eli Gray的FileSaver,我得到了它的工作(chrome):

bb = new window.WebKitBlobBuilder;
var svg = $('#designpanel').svg('get');
bb.append(svg.toSVG());
var blob = bb.getBlob("application/svg+xml;charset=" + svg.characterSet);
saveAs(blob,"name.svg");
Run Code Online (Sandbox Code Playgroud)

SVG来自keith woods jquery的svg.

Html Rocks 1

Html Rocks 2


use*_*898 7

	// save SVG
	$('#SVGsave').click(function(){
		var a      = document.createElement('a');
		a.href     = 'data:image/svg+xml;utf8,' + unescape($('#SVG')[0].outerHTML);
		a.download = 'plot.svg';
		a.target   = '_blank';
		document.body.appendChild(a); a.click(); document.body.removeChild(a);
	});
Run Code Online (Sandbox Code Playgroud)

  • 你救了五天!如果它存在,我会给你一个stackoverflow-gold! (2认同)

小智 5

我最近发现了这个Chrome插件http://nytimes.github.io/svg-crowbar/.这对我的需求来说有点儿麻烦但基本上有效.

我以前做过一个类似于接受的答案的解决方案,它涉及一个服务器端脚本,但是它很长,并且还存在所有样式必须在标记中内联的问题.撬棍似乎为你照顾,这很好.


Dav*_*vid 5

我正在回答这个话题,尽管已经有几年了,因为最近网络浏览器在支持SVG和其他相关行为方面的融合已经引起了人们对SVG的兴趣,并允许对这个问题进行"普遍"回答.本质上zneak的方法是正确的,但在我看来,简洁(即我需要一段时间让它为自己工作).我也认为他对AJAX的引用要么不必要,要么不是我对AJAX的理解(=使用XMLHttpRequest).因此,我将使用纯JavaScript(即没有JQuery或任何其他库)提供更详细的答案,并为Java,Perl和PHP提供服务器代码.

(1)将HTML页面中的(动态生成的)SVG内容包含在具有唯一ID的div中,例如

<div id="svg"><svg...>SVG content</svg></div>

(2)包含一个调用JavaScript函数的按钮,例如

<button onclick="sendSVG();">Save as SVG File</button>

(3)包括按钮标记中指定的JavaScript函数:

function sendSVG() 
{
   var svgText = document.getElementById('svg').innerHTML;

   var form = document.createElement("form");
   form.setAttribute("method", "post");
   form.setAttribute("action", "http://path-to-your-server-app");
   form.setAttribute("accept-charset", "UTF-8");

   var hiddenSVGField = document.createElement("input");    
   hiddenSVGField.setAttribute("type", "hidden");
   hiddenSVGField.setAttribute("name", "svgText");
   hiddenSVGField.setAttribute("value", svgText);

   form.appendChild(hiddenSVGField);
   document.body.appendChild(form);
   form.submit();
}
Run Code Online (Sandbox Code Playgroud)

(4)编写服务器应用程序以接受您的SVGtext帖子请求,并使用Content-Disposition返回为image/svg + xml以指定附件.提供了三种语言的工作代码,虽然我不是Perl程序员,并且从未在愤怒中使用过PHP.

Java Servlet

public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
{
   String svgText = (String) request.getParameter("svgText");
   response.setContentType("image/svg+xml");
   response.addHeader("Content-Disposition", "attachment; filename=\"image.svg\"");
   PrintWriter out = response.getWriter();
   out.println(svgText);
}
Run Code Online (Sandbox Code Playgroud)

Perl CGI

use CGI qw(:standard);
my $svgText = param('svgText');
print header(-type => "image/svg+xml",
    -content_disposition => "attachment; filename=image.svg");      
print $svgText;
Run Code Online (Sandbox Code Playgroud)

PHP

<?php
   $svgText = $_POST['svgText'];
   header('Content-type: image/svg+xml');
   header('Content-Disposition: attachment; filename="image.svg"'); 
   print "$svgText";
?>
Run Code Online (Sandbox Code Playgroud)

我在这里使用了一个硬编码的名称(image.svg),但实际上从页面中获取了我生成的动态内容的描述符(再次使用div和ID document.getElementById('graphName').textContent).

这已在Mac Safari 9,Firefox 42,Chrome 47,Opera 34以及Windows7/IE 11和Windows10/Edge上进行了测试,并且在每种情况下都会下载svg文件或提示下载它.生成的文件将打开,例如Adobe Illustrator或您设置为打开svg文件的任何其他应用程序.

一个真实世界的例子(如果你考虑学术研究真实世界)是在Gene部分的http://flyatlas.gla.ac.uk/MidgutAtlas/index.html.