Voglio convertire SVG in immagini bitmap (come JPEG, PNG, ecc.) Tramite JavaScript.
Voglio convertire SVG in immagini bitmap (come JPEG, PNG, ecc.) Tramite JavaScript.
Risposte:
Ecco come puoi farlo tramite JavaScript:
toImage()
e anche download()
per un'immagine scaricata automaticamente.
La soluzione jbeard4 ha funzionato magnificamente.
Sto usando Raphael SketchPad per creare un SVG. Collegamento ai file al passaggio 1.
Per un pulsante Salva (id di svg è "editor", id di canvas è "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
ma la funzione jquery html () non aggiunge il tag svg, quindi questo codice funziona per me ma dovevo modificare il canvg livecanvg('canvas', '<svg>'+$("#editor").html()+'</svg>');
$(selector).html()
il genitore del tuo elemento svg , funzionerà
html()
involucri o costruire manualmente il svg
tag principale , che potrebbe anche avere attributi che lasci fuori da questo hack. Basta usare $(svg_elem)[0].outerHTML
ti dà la fonte completa di svg e il suo contenuto.
Questo sembra funzionare nella maggior parte dei browser:
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()
La soluzione per convertire SVG in URL BLOB e URL BLOB in immagine PNG
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;
}
Ho scritto questa classe ES6 che fa il lavoro.
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;
}
}
Ecco come lo usi
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.
});
Se desideri una versione JavaScript vaniglia, puoi visitare il sito Web di Babel e compilare il codice lì.
Ecco una soluzione lato server basata su PhantomJS. È possibile utilizzare JSONP per effettuare una chiamata tra domini al servizio immagine:
https://github.com/vidalab/banquo-server
Per esempio:
Quindi puoi visualizzare l'immagine con il tag img:
<img src="data:image/png;base64, [base64 data]"/>
Funziona su browser.
cambia svg
per abbinare il tuo elemento
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
può essere convertito in base alle condizioni:
svg
è in formato percorsi SVG (stringa) :
new Path2D()
e imposta svg
come parametrocanvas.toDataURL()
come src
.esempio:
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;
Si noti che Path2D
non è supportato ie
e parzialmente supportato in Edge. Polyfill risolve questo problema:
https://github.com/nilzona/path2d-polyfill
svg
blob e disegna su tela usando .drawImage()
:
Bella descrizione: http://ramblings.mcpher.com/Home/excelquirks/gassnips/svgtopng
Si noti che in ie si otterrà un'eccezione sullo stage di canvas.toDataURL (); È perché IE ha una restrizione di sicurezza troppo elevata e considera il canvas immediatamente dopo aver disegnato l'immagine lì. Tutti gli altri browser limitano solo se l'immagine è di origine incrociata.
canvg
libreria JavaScript. È una libreria separata ma ha funzioni utili.Piace:
ctx.drawSvg(rawSvg);
var dataURL = canvas.toDataURL();
Di recente ho scoperto un paio di librerie di tracciamento di immagini per JavaScript che sono effettivamente in grado di costruire un'approssimazione accettabile per la bitmap, sia per dimensioni che per qualità. Sto sviluppando questa libreria JavaScript e CLI:
https://www.npmjs.com/package/svg-png-converter
Che fornisce API unificate per tutti loro, supportando browser e nodo, non dipendenti dal DOM, e uno strumento da riga di comando.
Per convertire loghi / cartoni animati / immagini simili, fa un ottimo lavoro. Per le foto / il realismo sono necessarie alcune modifiche poiché le dimensioni dell'output possono crescere molto.
Ha un parco giochi anche se in questo momento sto lavorando a uno migliore, più facile da usare, poiché sono state aggiunte più funzionalità:
https://cancerberosgx.github.io/demos/svg-png-converter/playground/#