Frage So speichern Sie Svg-Canvas im lokalen Dateisystem


Gibt es eine Möglichkeit, einem Benutzer, nachdem er ein Vektor-Diagramm auf einem Javascript-Svg-Canvas mit einem Browser erstellt hat, zu erlauben, diese Datei in ihr lokales Dateisystem herunterzuladen?

SVG ist ein völlig neues Feld für mich, also bitte gedulden Sie sich, wenn meine Formulierung nicht korrekt ist.


75
2018-03-20 17:05


Ursprung


Antworten:


Es könnte möglich sein, den normalen "Save" -Browserbefehl zu verwenden, aber es wird nicht nur die SVG-Leinwand gespeichert, sondern auch die ganze Seite.

Ich glaube, Ihre beste Wette ist, AJAX zu verwenden und die ganzen SVG XML-Daten als POST-Daten an ein Serverskript zu senden, und dieses Skript sendet einfach die POST-Daten mit der Überschrift zurück Content-Disposition: attachment; filename=yourfile.svg.

(Unter PHP können Sie den rohen POST-Inhalt mit erhalten file_get_contents('php://input').)


15
2018-03-20 17:15



Sie können eine Hin- und Rückfahrt zum Server vermeiden.

Base64 kodiere dein SVG XML.

Erstellen Sie dann eine Verknüpfung zu diesen Daten. Der Benutzer kann mit der rechten Maustaste klicken, um es lokal zu speichern.

// 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>"));
}

Das img-Tag funktioniert in Webkit, der Link funktioniert in Webkit & Firefox und funktioniert möglicherweise in jedem Browser, der unterstützt data-uri


64
2017-11-19 18:10



Es ist nicht notwendig, die base64-Kodierung zu machen - Sie können eine Verbindung mit rohen SVG-Code darin erstellen. Hier ist eine modifizierte Funktion encode_as_img_and_link () aus The_Who's Antwort:

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')
  );
}

18
2018-04-11 15:29



Verwenden Dateiserver.js

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

17
2018-03-20 19:36



Mit Dateiserver von Eli Grey Ich habe es funktioniert (Chrom):

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");

SVG ist von keith woods jquery's svg.

Html Felsen 1

Html Felsen 2


10
2018-02-15 11:43



	// 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);
	});


7
2017-09-16 13:08



Ich habe dieses Chrome-Plugin kürzlich gefunden http://nytimes.github.io/svg-crowbar/. Es ist ein bisschen Buggy für meine Bedürfnisse, aber funktioniert im Wesentlichen.

Ich hatte zuvor eine Lösung ähnlich der angenommenen Antwort gemacht, die ein serverseitiges Skript beinhaltete, aber es war ziemlich langatmig und hatte auch das Problem, dass alle Styles im Markup inline sein mussten. Crowbar scheint sich darum für dich zu kümmern, was nett ist.


5
2018-01-07 15:26



Ich antworte auf dieses Thema, obwohl es ein paar Jahre alt ist, weil die jüngste Konvergenz von Webbrowsern in ihrer Unterstützung für SVG und andere relevante Verhaltensweisen erneutes Interesse an SVG hervorgerufen hat und eine "universelle" Antwort auf die Frage erlaubt. Im Wesentlichen ist der Ansatz von zneak korrekt, aber meiner Meinung nach knappe (d. H. Es hat eine Weile gedauert, bis es für mich selbst funktionierte). Ich denke auch, dass sein Verweis auf AJAX entweder unnötig ist oder nicht, was ich von AJAX verstehe (= verwendet ein XMLHttpRequest). Ich werde daher eine detailliertere Antwort mit reinem JavaScript (d. H. Ohne JQuery oder eine andere Bibliothek) geben und Servercode für Java, Perl und PHP bereitstellen.

(1) Lassen Sie den (dynamisch generierten) SVG-Inhalt in Ihrer HTML-Seite in ein div mit einer eindeutigen ID, z.B.

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

(2) Einschließen einer Schaltfläche zum Aufrufen der JavaScript-Funktion, z.

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

(3) Schließen Sie die JavaScript-Funktion ein, die in Ihrem Schaltflächen-Markup angegeben ist:

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();
}

(4) Schreiben Sie eine Server-App, um Ihre SVGtext-Post-Anfrage zu akzeptieren und als Bild / SVG + XML mit Content-Disposition zurückzusenden, um eine Anlage zu spezifizieren. Arbeitscode in drei Sprachen wird vorgestellt, obwohl ich kein Perl-Programmierer bin und PHP nie im Zorn benutzt habe.

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);
}

Perl CGI

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

PHP

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

Ich habe hier einen hartcodierten Namen für das Bild (image.svg) verwendet, aber ich nehme tatsächlich einen Deskriptor des dynamischen Inhalts auf, den ich von der Seite erzeuge (indem ich wieder div und eine ID verwende und document.getElementById('graphName').textContent).

Dies wurde auf Mac Safari 9, Firefox 42, Chrome 47, Opera 34 und Windows 7 / IE 11 und Windows 10 / Edge getestet und in jedem Fall wird die Svg-Datei heruntergeladen oder man wird aufgefordert, sie herunterzuladen. Die resultierenden Dateien werden z.B. Adobe Illustrator oder eine andere Anwendung, die Sie zum Öffnen von Svg-Dateien eingerichtet haben.

Ein realistisches Beispiel dafür (wenn man akademische Forschung in der realen Welt betrachtet) ist http://flyatlas.gla.ac.uk/MidgutAtlas/index.html in der Gene-Sektion.


5
2018-01-12 15:35



Ja ist es möglich. Verwenden Sie jquery.svg http://keith-wood.name/svgRef.html und posten Sie die Svg XML-Daten mit der Funktion svg.toSVG () (Schreiben in ein verstecktes Feld beim Senden). Lassen Sie den php speichern und konvertieren in Raster mit imagemagick (convert image.svg image.png) dann zwingen Sie die Datei zum Download mit Header ("Content-Type: application / octet-stream") und readfile das Bild.


2
2018-06-08 14:14