如何将 svg 画布保存到本地文件系统
有没有办法允许用户在使用浏览器在 javascript svg 画布上创建矢量图之后,将此文件下载到本地文件系统?
SVG 对我来说是一个全新的领域,所以如果我的措辞不准确,请耐心等待。
Is there a way to allow a user, after he has created a vector graph on a javascript svg canvas using a browser, to download this file to their local filesystem?
SVG is a total new field for me so please be patient if my wording is not accurate.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(15)
您可以避免往返服务器。
对 SVG xml 进行 Base64 编码。
然后生成该数据的链接。用户可以右键单击将其保存到本地。
img 标签在 Webkit 中有效,链接在 Webkit 中有效Firefox,并且可以在任何支持
data-uri
的浏览器中运行You can avoid a round trip to the server.
Base64 encode your SVG xml.
Then generate a link to that data. The user can right click on to save it locally.
The img tag works in Webkit, the link works in Webkit & Firefox, and may work in any browser which supports
data-uri
使用 FileSaver.js
Using FileSaver.js
无需进行 Base64 编码 - 您可以创建包含原始 SVG 代码的链接。这是 The_Who 的答案中经过修改的函数encode_as_img_and_link():
There is no need to do base64 encoding - you can create a link with raw SVG code in it. Here is a modified function encode_as_img_and_link() from The_Who's answer:
可能可以使用常规的“保存”浏览器命令,但它不仅会保存 SVG 画布,还会保存整个页面。
我相信您最好的选择是使用 AJAX 并将整个 SVG XML 数据作为 POST 数据发送到服务器脚本,然后让该脚本仅发送回带有标题
Content-Disposition:attachment; 的 POST 数据。文件名=yourfile.svg
。(在 PHP 下,您可以使用
file_get_contents('php://input')
获取原始 POST 内容。)It might be possible using the regular "Save" browser command, but it won't just save the SVG canvas, it will save the whole page.
I believe your best bet is to use AJAX and send the whole SVG XML data as POST data to a server script, and have that script just send back the POST data with the header
Content-Disposition: attachment; filename=yourfile.svg
.(Under PHP, you can get the raw POST contents with
file_get_contents('php://input')
.)使用 Eli Gray 的 FileSaver 我让它工作了(chrome):
SVG 来自 keith woods jquery 的 svg。
Html Rocks 1
Html Rocks 2
With FileSaver from Eli Grey I got it working (chrome):
SVG is from keith woods jquery's svg.
Html Rocks 1
Html Rocks 2
我最近发现了这个 Chrome 插件 http://nytimes.github.io/svg-crowbar/ 。这对于我的需求来说有点问题,但基本上可以用。
我之前曾提出过一个类似于已接受的答案的解决方案,其中涉及服务器端脚本,但它相当冗长,而且还存在所有样式都必须内联在标记中的问题。 Crowbar 似乎会帮你解决这个问题,这很好。
I recently found this Chrome plugin http://nytimes.github.io/svg-crowbar/. It's a bit buggy for my needs but essentially works.
I had previously made a solution similar to the accepted answer which involved a serverside script but it's quite long winded and also had the problem that all the styles had to be inline in the markup. Crowbar seems to take care of that for you, which is nice.
我正在回答这个主题,尽管它已经有几年的历史了,因为最近 Web 浏览器在支持 SVG 和其他相关行为方面的融合已经引起了人们对 SVG 的新兴趣,并允许对这个问题有一个“通用”答案。从本质上讲,zneak 的方法是正确的,但在我看来,它很简洁(即我花了一段时间才让它为自己工作)。我还认为他对 AJAX 的引用要么是不必要的,要么不是我所理解的 AJAX(= 使用 XMLHttpRequest)。因此,我将使用纯 JavaScript(即没有 JQuery 或任何其他库)提供更详细的答案,并提供 Java、Perl 和 PHP 的服务器代码。
(1) 将 HTML 页面中的(动态生成的)SVG 内容包含在具有唯一 ID 的 div 中,例如
(2) 包含一个调用 JavaScript 函数的按钮,例如
(3) 包含在按钮标记中命名的 JavaScript 函数:
(4) 编写一个服务器应用程序来接受您的 SVGtext post 请求,并使用 Content-Disposition 以指定附件的形式返回 image/svg+xml。提供了三种语言的工作代码,尽管我不是 Perl 程序员,也从未愤怒地使用过 PHP。
Java Servlet
Perl CGI
PHP
我在这里为图像使用了硬编码名称 (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 文件的任何其他应用程序中打开。
一个真实的例子(如果您考虑现实世界的学术研究)位于 http: //flyatlas.gla.ac.uk/MidgutAtlas/index.html 在基因部分。
I'm replying to this topic, even though it's a few years old, because the recent convergence of web browsers in their support for SVG and other relevant behaviour has produced renewed interest in SVG and allows a 'universal' answer to the question. In essence zneak's approach is correct but, in my opinion, terse (i.e. it took me a while to get it working for myself). I also think that his reference to AJAX is either unnecessary or not what I understand by AJAX (= uses an XMLHttpRequest). I shall therefore provide a more detailed answer using pure JavaScript (i.e. without JQuery or any other library) and provide server code for Java, Perl and PHP.
(1) Have the (dynamically generated) SVG content in your HTML page enclosed in a div with a unique ID, e.g.
<div id="svg"><svg...>SVG content</svg></div>
(2) Include a button to invoke the JavaScript function, e.g.
<button onclick="sendSVG();">Save as SVG File</button>
(3) Include the JavaScript function named in your button markup:
(4) Write a server app to accept your SVGtext post request and return as image/svg+xml using Content-Disposition to specify an attachment. Working code in three languages is presented, although I am not a Perl programmer and have never used PHP in anger.
Java Servlet
Perl CGI
PHP
I have used a hard-coded name for the image here (image.svg), but actually pick up a discriptor of the dynamic content I generate from the page (using a div and an ID again, and
document.getElementById('graphName').textContent
).This has been tested on Mac Safari 9, Firefox 42, Chrome 47, Opera 34, and Windows7/IE 11 and Windows10/Edge and in each case the svg file is downloaded or one is prompted to download it. The resulting files will open in, e.g. Adobe Illustrator or whatever other application you have set to open svg files.
A real-world example of this (if you consider academic research real-world) is at http://flyatlas.gla.ac.uk/MidgutAtlas/index.html in the Gene section.
是的,有可能吗?使用 jquery.svg http://keith-wood.name/svgRef.html 并发布使用函数 svg.toSVG() 的 svg xml 数据(在提交时写入隐藏字段)。
让 php 使用 imagemagick 保存并转换为光栅(转换 image.svg image.png),然后使用 header("Content-Type: application/octet-stream") 强制文件下载并读取图像。
Yes is it possible. Use jquery.svg http://keith-wood.name/svgRef.html and post the svg xml data using the function svg.toSVG() (writing into a hidden field on submit).
Have the php save and convert to raster using imagemagick (convert image.svg image.png) then force the file to download using header("Content-Type: application/octet-stream") and readfile the image.
最兼容的方式是往返服务器。您还可以在某些浏览器中使用 data: URI。
Most compatible way would be a round-trip to the server. You could also use a data: URI in some browsers.
您无法使用 javascript 将任何内容保存到本地文件系统,您应该做的是将
canvas
的内容发送到服务器并让用户下载并保存它。You can't save anything with javascript to the local filesystem, what you should do is send the contents of the
canvas
to the server and make the user download and save that.回答我自己的问题:
另一种可能性(虽然不是最好的)是在网页上显示序列化内容并让用户选择、复制和粘贴它。
这是在研究了伊莱·格雷的解决方案之后。
To answer my own question:
Another possibility though not the nicest is to display the serialized contents on the webpage and have the user select, copy and paste that.
This after investigating eli grey's solution.
我可能发现了一种更好的方法,不强迫用户按右键单击“图像另存为”。只需将画布的 base64 代码实时绘制到链接的 href 中并对其进行修改,以便下载将自动开始。我不知道它的通用浏览器是否兼容,但它应该适用于主要/新浏览器。
请随意将 a 包裹在您想要的任何内容上,希望有所帮助
I maybe discovered a better way for not forcing the user to press right click "save image as". just live draw the canvas base64 code into the href of the link and modify it so the download will start automatically. i dont know if its universal browser compatible but it should work with the main/new browsers.
feel free to wrap the a around anything you want, hope that helps a bit
根本不需要进行任何编程。人们已经为此构建了一些在线应用程序,其中包括可定义的参数,例如尺寸、分辨率、输出格式等。
这是我为 svg->jpeg 找到的更好的在线图像转换应用程序之一。http://image.online-convert.com/convert-to-jpg
No need to do any programming at all. There are online apps people have already built for that, and include definable parameters such as dimensions, resolution, output format etc.
This is one of the better online image conversion apps I've found for svg->jpeg.http://image.online-convert.com/convert-to-jpg