Quero converter SVG em imagens de bitmap (como JPEG, PNG etc.) através de JavaScript.
Quero converter SVG em imagens de bitmap (como JPEG, PNG etc.) através de JavaScript.
Respostas:
Aqui está como você pode fazer isso através do JavaScript:
toImage()
e também download()
para obter uma imagem baixada automaticamente.
A solução jbeard4 funcionou lindamente.
Estou usando o Raphael SketchPad para criar um SVG. Link para os arquivos na etapa 1.
Para um botão Salvar (o id do svg é "editor", o id do 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
mas a função jquery html () não adicionar tag svg, de modo que este código funciona para mim, mas eu precisava para editar o canvg ao vivo paracanvg('canvas', '<svg>'+$("#editor").html()+'</svg>');
$(selector).html()
no pai de sua SVG elemento, ele vai trabalhar
html()
em wrappers ou construir manualmente a svg
tag pai - que pode até ter atributos que você deixa de fora com esse hack. Apenas use $(svg_elem)[0].outerHTML
fornece a fonte completa do svg e seu conteúdo. Apenas dizendo ...
Isso parece funcionar na maioria dos navegadores:
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()
A solução para converter SVG para URL de blob e URL de blob para imagem 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;
}
Eu escrevi essa classe ES6 que faz o trabalho.
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;
}
}
Aqui está como você o usa
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 você quiser uma versão JavaScript de baunilha, poderá acessar o site da Babel e transpilar o código para lá.
Aqui está uma solução do lado do servidor baseada no PhantomJS. Você pode usar JSONP para fazer uma chamada entre domínios para o serviço de imagem:
https://github.com/vidalab/banquo-server
Por exemplo:
Então você pode exibir a imagem com a tag img:
<img src="data:image/png;base64, [base64 data]"/>
Funciona através do navegador.
mude svg
para combinar com seu 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
a png
pode ser convertida de acordo com as condições de:
svg
estiver no formato SVG (string) de caminhos :
new Path2D()
e definir svg
como parâmetrocanvas.toDataURL()
como src
.exemplo:
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;
Observe que Path2D
não é suportado ie
e parcialmente suportado na borda. O Polyfill resolve isso:
https://github.com/nilzona/path2d-polyfill
svg
blob e desenhe na tela usando .drawImage()
:
Boa descrição: http://ramblings.mcpher.com/Home/excelquirks/gassnips/svgtopng
Note que em ie você receberá uma exceção no palco do canvas.toDataURL (); Isso ocorre porque o IE possui uma restrição de segurança muito alta e trata a tela como somente leitura após desenhar a imagem lá. Todos os outros navegadores restringem apenas se a imagem for de origem cruzada.
canvg
biblioteca JavaScript. É uma biblioteca separada, mas possui funções úteis.Gostar:
ctx.drawSvg(rawSvg);
var dataURL = canvas.toDataURL();
Recentemente, descobri algumas bibliotecas de rastreamento de imagens para JavaScript que realmente são capazes de criar uma aproximação aceitável ao bitmap, tanto em tamanho quanto em qualidade. Estou desenvolvendo esta biblioteca JavaScript e CLI:
https://www.npmjs.com/package/svg-png-converter
Que fornece API unificada para todos eles, suportando navegador e nó, não dependendo do DOM, e uma ferramenta de linha de comando.
Para converter logotipos / desenhos animados / imagens semelhantes, ele faz um excelente trabalho. Para fotos / realismo, são necessários alguns ajustes, pois o tamanho da saída pode aumentar bastante.
Tem um playground, embora agora eu esteja trabalhando em um melhor, mais fácil de usar, pois mais recursos foram adicionados:
https://cancerberosgx.github.io/demos/svg-png-converter/playground/#