Ich möchte SVG über JavaScript in Bitmap-Bilder (wie JPEG, PNG usw.) konvertieren.
Ich möchte SVG über JavaScript in Bitmap-Bilder (wie JPEG, PNG usw.) konvertieren.
Antworten:
So können Sie dies mit JavaScript tun:
toImage()
und auch download()
für ein automatisch heruntergeladenes Bild.
Die jbeard4-Lösung hat wunderbar funktioniert.
Ich verwende Raphael SketchPad , um eine SVG zu erstellen. Link zu den Dateien in Schritt 1.
Für eine Schaltfläche Speichern (ID von svg ist "editor", ID von canvas ist "canvas"):
$("#editor_save").click(function() {
// the canvg call that takes the svg xml and converts it to a canvas
canvg('canvas', $("#editor").html());
// the canvas calls to output a png
var canvas = document.getElementById("canvas");
var img = canvas.toDataURL("image/png");
// do what you want with the base64, write to screen, post to server, etc...
});
<svg>...</svg
aber die Funktion jquery html () fügt kein svg-Tag hinzu, daher funktioniert dieser Code für mich, aber ich musste das canvg live bearbeitencanvg('canvas', '<svg>'+$("#editor").html()+'</svg>');
$(selector).html()
das übergeordnete Element Ihres svg- Elements aufrufen , wird es funktionieren
html()
für Wrapper verwenden oder das übergeordnete svg
Tag manuell erstellen müssen - möglicherweise sogar Attribute, die Sie bei diesem Hack auslassen. Durch die einfache Verwendung erhalten $(svg_elem)[0].outerHTML
Sie die vollständige Quelle des SVG und seines Inhalts.
Dies scheint in den meisten Browsern zu funktionieren:
function copyStylesInline(destinationNode, sourceNode) {
var containerElements = ["svg","g"];
for (var cd = 0; cd < destinationNode.childNodes.length; cd++) {
var child = destinationNode.childNodes[cd];
if (containerElements.indexOf(child.tagName) != -1) {
copyStylesInline(child, sourceNode.childNodes[cd]);
continue;
}
var style = sourceNode.childNodes[cd].currentStyle || window.getComputedStyle(sourceNode.childNodes[cd]);
if (style == "undefined" || style == null) continue;
for (var st = 0; st < style.length; st++){
child.style.setProperty(style[st], style.getPropertyValue(style[st]));
}
}
}
function triggerDownload (imgURI, fileName) {
var evt = new MouseEvent("click", {
view: window,
bubbles: false,
cancelable: true
});
var a = document.createElement("a");
a.setAttribute("download", fileName);
a.setAttribute("href", imgURI);
a.setAttribute("target", '_blank');
a.dispatchEvent(evt);
}
function downloadSvg(svg, fileName) {
var copy = svg.cloneNode(true);
copyStylesInline(copy, svg);
var canvas = document.createElement("canvas");
var bbox = svg.getBBox();
canvas.width = bbox.width;
canvas.height = bbox.height;
var ctx = canvas.getContext("2d");
ctx.clearRect(0, 0, bbox.width, bbox.height);
var data = (new XMLSerializer()).serializeToString(copy);
var DOMURL = window.URL || window.webkitURL || window;
var img = new Image();
var svgBlob = new Blob([data], {type: "image/svg+xml;charset=utf-8"});
var url = DOMURL.createObjectURL(svgBlob);
img.onload = function () {
ctx.drawImage(img, 0, 0);
DOMURL.revokeObjectURL(url);
if (typeof navigator !== "undefined" && navigator.msSaveOrOpenBlob)
{
var blob = canvas.msToBlob();
navigator.msSaveOrOpenBlob(blob, fileName);
}
else {
var imgURI = canvas
.toDataURL("image/png")
.replace("image/png", "image/octet-stream");
triggerDownload(imgURI, fileName);
}
document.removeChild(canvas);
};
img.src = url;
}
.msToBlob()
Die Lösung zum Konvertieren von SVG in Blob-URL und Blob-URL in PNG-Bild
const svg=`<svg version="1.1" baseProfile="full" width="300" height="200"
xmlns="http://www.w3.org/2000/svg">
<rect width="100%" height="100%" fill="red" />
<circle cx="150" cy="100" r="80" fill="green" />
<text x="150" y="125" font-size="60" text-anchor="middle" fill="white">SVG</text></svg>`
svgToPng(svg,(imgData)=>{
const pngImage = document.createElement('img');
document.body.appendChild(pngImage);
pngImage.src=imgData;
});
function svgToPng(svg, callback) {
const url = getSvgUrl(svg);
svgUrlToPng(url, (imgData) => {
callback(imgData);
URL.revokeObjectURL(url);
});
}
function getSvgUrl(svg) {
return URL.createObjectURL(new Blob([svg], { type: 'image/svg+xml' }));
}
function svgUrlToPng(svgUrl, callback) {
const svgImage = document.createElement('img');
// imgPreview.style.position = 'absolute';
// imgPreview.style.top = '-9999px';
document.body.appendChild(svgImage);
svgImage.onload = function () {
const canvas = document.createElement('canvas');
canvas.width = svgImage.clientWidth;
canvas.height = svgImage.clientHeight;
const canvasCtx = canvas.getContext('2d');
canvasCtx.drawImage(svgImage, 0, 0);
const imgData = canvas.toDataURL('image/png');
callback(imgData);
// document.body.removeChild(imgPreview);
};
svgImage.src = svgUrl;
}
Ich habe diese ES6-Klasse geschrieben, die den Job macht.
class SvgToPngConverter {
constructor() {
this._init = this._init.bind(this);
this._cleanUp = this._cleanUp.bind(this);
this.convertFromInput = this.convertFromInput.bind(this);
}
_init() {
this.canvas = document.createElement("canvas");
this.imgPreview = document.createElement("img");
this.imgPreview.style = "position: absolute; top: -9999px";
document.body.appendChild(this.imgPreview);
this.canvasCtx = this.canvas.getContext("2d");
}
_cleanUp() {
document.body.removeChild(this.imgPreview);
}
convertFromInput(input, callback) {
this._init();
let _this = this;
this.imgPreview.onload = function() {
const img = new Image();
_this.canvas.width = _this.imgPreview.clientWidth;
_this.canvas.height = _this.imgPreview.clientHeight;
img.crossOrigin = "anonymous";
img.src = _this.imgPreview.src;
img.onload = function() {
_this.canvasCtx.drawImage(img, 0, 0);
let imgData = _this.canvas.toDataURL("image/png");
if(typeof callback == "function"){
callback(imgData)
}
_this._cleanUp();
};
};
this.imgPreview.src = input;
}
}
So verwenden Sie es
let input = "https://restcountries.eu/data/afg.svg"
new SvgToPngConverter().convertFromInput(input, function(imgData){
// You now have your png data in base64 (imgData).
// Do what ever you wish with it here.
});
Wenn Sie eine Vanille-JavaScript-Version wünschen, können Sie zur Babel-Website gehen und den Code dort transpilieren.
Hier ist eine serverseitige Lösung, die auf PhantomJS basiert. Mit JSONP können Sie den Image-Service domänenübergreifend aufrufen:
https://github.com/vidalab/banquo-server
Beispielsweise:
Dann können Sie das Bild mit dem img-Tag anzeigen:
<img src="data:image/png;base64, [base64 data]"/>
Es funktioniert browserübergreifend.
Ändern Sie svg
, um Ihrem Element zu entsprechen
function svg2img(){
var svg = document.querySelector('svg');
var xml = new XMLSerializer().serializeToString(svg);
var svg64 = btoa(xml); //for utf8: btoa(unescape(encodeURIComponent(xml)))
var b64start = 'data:image/svg+xml;base64,';
var image64 = b64start + svg64;
return image64;
};svg2img()
Uncaught TypeError: Failed to execute 'serializeToString' on 'XMLSerializer': parameter 1 is not of type 'Node'.
Svg
to png
kann abhängig von den Bedingungen konvertiert werden:
svg
im Format SVG (String) Pfade ist :
new Path2D()
und svg
als Parameter festlegencanvas.toDataURL()
als src
.Beispiel:
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
let svgText = 'M10 10 h 80 v 80 h -80 Z';
let p = new Path2D('M10 10 h 80 v 80 h -80 Z');
ctx.stroke(p);
let url = canvas.toDataURL();
const img = new Image();
img.src = url;
Beachten Sie, dass dies in Edge Path2D
nicht ie
und teilweise in Edge unterstützt wird. Polyfill löst Folgendes:
https://github.com/nilzona/path2d-polyfill
svg
Blob und zeichnen Sie auf Leinwand mit .drawImage()
:
Schöne Beschreibung: http://ramblings.mcpher.com/Home/excelquirks/gassnips/svgtopng
Beachten Sie, dass Sie in dh auf der Bühne von canvas.toDataURL () eine Ausnahme erhalten; Dies liegt daran, dass der IE zu hohe Sicherheitsbeschränkungen aufweist und die Leinwand nach dem Zeichnen des Bilds als schreibgeschützt behandelt. Alle anderen Browser schränken nur ein, wenn das Bild einen Kreuzursprung aufweist.
canvg
JavaScript-Bibliothek. Es ist eine separate Bibliothek, hat aber nützliche Funktionen.Mögen:
ctx.drawSvg(rawSvg);
var dataURL = canvas.toDataURL();
Ich habe kürzlich einige Bildverfolgungsbibliotheken für JavaScript entdeckt, die tatsächlich eine akzeptable Annäherung an die Bitmap erstellen können, sowohl in Bezug auf Größe als auch Qualität. Ich entwickle diese JavaScript-Bibliothek und CLI:
https://www.npmjs.com/package/svg-png-converter
Dies bietet eine einheitliche API für alle, unterstützt Browser und Knoten, unabhängig vom DOM, und ein Befehlszeilentool.
Zum Konvertieren von Logos / Cartoons / ähnlichen Bildern macht es hervorragende Arbeit. Für Fotos / Realismus sind einige Anpassungen erforderlich, da die Ausgabegröße stark ansteigen kann.
Es gibt einen Spielplatz, obwohl ich gerade an einem besseren arbeite, der einfacher zu bedienen ist, da weitere Funktionen hinzugefügt wurden:
https://cancerberosgx.github.io/demos/svg-png-converter/playground/#