Je veux convertir SVG en images bitmap (comme JPEG, PNG, etc.) via JavaScript.
Je veux convertir SVG en images bitmap (comme JPEG, PNG, etc.) via JavaScript.
Réponses:
Voici comment vous pouvez le faire via JavaScript:
toImage()
et aussi download()
pour une image téléchargée automatiquement.
La solution jbeard4 a parfaitement fonctionné.
J'utilise Raphael SketchPad pour créer un SVG. Lien vers les fichiers de l'étape 1.
Pour un bouton Enregistrer (l'id de svg est "éditeur", l'id de canvas est "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
mais la fonction jquery html () n'ajoute pas de balise svg, donc ce code fonctionne pour moi mais j'avais besoin de modifier le canvg en directcanvg('canvas', '<svg>'+$("#editor").html()+'</svg>');
$(selector).html()
le parent de votre élément svg , cela fonctionnera
html()
sur des wrappers, ou construire manuellement la svg
balise parent - qui pourrait même avoir des attributs que vous omettez avec ce hack. Une simple utilisation $(svg_elem)[0].outerHTML
vous donne la source complète du svg et de son contenu. Je dis juste ...
Cela semble fonctionner dans la plupart des navigateurs:
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 solution pour convertir SVG en URL blob et URL blob en image 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;
}
J'ai écrit cette classe ES6 qui fait le travail.
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;
}
}
Voici comment vous l'utilisez
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.
});
Si vous voulez une version JavaScript vanille, vous pouvez vous rendre sur le site Babel et y transpiler le code.
Voici une solution côté serveur basée sur PhantomJS. Vous pouvez utiliser JSONP pour effectuer un appel interdomaine au service d'imagerie:
https://github.com/vidalab/banquo-server
Par exemple:
Ensuite, vous pouvez afficher l'image avec la balise img:
<img src="data:image/png;base64, [base64 data]"/>
Cela fonctionne à travers le navigateur.
changer svg
pour correspondre à votre élément
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
à png
convertir selon les conditions:
svg
est au format SVG (chaîne) :
new Path2D()
et définir svg
comme paramètrecanvas.toDataURL()
comme src
.exemple:
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;
Notez que Path2D
non pris en charge dans ie
et partiellement pris en charge dans Edge. Polyfill résout cela:
https://github.com/nilzona/path2d-polyfill
svg
blob et dessinez sur un canevas en utilisant .drawImage()
:
Belle description: http://ramblings.mcpher.com/Home/excelquirks/gassnips/svgtopng
Notez que dans ie vous obtiendrez une exception sur scène de canvas.toDataURL (); C'est parce qu'IE a une restriction de sécurité trop élevée et traite le canevas en lecture seule après y avoir dessiné une image. Tous les autres navigateurs ne restreignent que si l'image est d'origine croisée.
canvg
bibliothèque JavaScript. Il s'agit d'une bibliothèque distincte mais a des fonctions utiles.Comme:
ctx.drawSvg(rawSvg);
var dataURL = canvas.toDataURL();
J'ai récemment découvert quelques bibliothèques de suivi d'image pour JavaScript qui sont en effet capables de construire une approximation acceptable du bitmap, à la fois en taille et en qualité. Je développe cette bibliothèque JavaScript et CLI:
https://www.npmjs.com/package/svg-png-converter
Qui fournit une API unifiée pour tous, prenant en charge le navigateur et le nœud, sans dépendre du DOM, et un outil de ligne de commande.
Pour convertir des logos / dessins animés / images similaires, il fait un excellent travail. Pour les photos / réalisme, quelques ajustements sont nécessaires car la taille de sortie peut augmenter considérablement.
Il a une aire de jeux, bien que je travaille actuellement sur une meilleure, plus facile à utiliser, car plus de fonctionnalités ont été ajoutées:
https://cancerberosgx.github.io/demos/svg-png-converter/playground/#