Je veux convertir SVG en images bitmap (comme JPEG, PNG, etc.) via JavaScript.
Réponses
Trop de publicités?Mon cas d'utilisation était d'avoir les données svg chargées à partir d'un réseau et cette classe ES6 a 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 l'utiliser
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 vanille de JavaScript, vous pourriez rendez-vous sur le site de Babel et transpilez le code là.
Ici, une fonction qui fonctionne sans bibliothèques et renvoie un Promesse :
/**
* converts a base64 encoded data url SVG image to a PNG image
* @param originalBase64 data url of svg image
* @param width target width in pixel of PNG image
* @return {Promise<String>} resolves to png data url of the image
*/
function base64SvgToBase64Png (originalBase64, width) {
return new Promise(resolve => {
let img = document.createElement('img');
img.onload = function () {
document.body.appendChild(img);
let canvas = document.createElement("canvas");
let ratio = (img.clientWidth / img.clientHeight) || 1;
document.body.removeChild(img);
canvas.width = width;
canvas.height = width / ratio;
let ctx = canvas.getContext("2d");
ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
try {
let data = canvas.toDataURL('image/png');
resolve(data);
} catch (e) {
resolve(null);
}
};
img.src = originalBase64;
});
}
Sur Firefox, il y a un problème pour les SVG sans largeur/hauteur définie .
Voir ceci exemple de travail incluant un correctif pour le problème de Firefox.
Voici une solution côté serveur basée sur PhantomJS. Vous pouvez utiliser JSONP pour faire un appel inter-domaine à image.vida.io.
Votre graphique/visualisation doit être accessible de l'extérieur. Vous pouvez passer des informations d'identification à l'URL.
Vous pouvez ensuite afficher l'image avec la balise img :
<img src="data:image/png;base64, [base64 data]"/>
Il fonctionne sur tous les navigateurs.
Svg
a png
peut être converti en fonction des conditions :
- Si
svg
est en format Chemins d'accès SVG (chaîne) :
- créer une toile
- créer
new Path2D()
et mettresvg
comme paramètre - dessiner un chemin sur une toile
- créer une image et l'utiliser
canvas.toDataURL()
commesrc
.
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 soutenu en bordure. Le polyfill résout ce problème : https://github.com/nilzona/path2d-polyfill
- Créer
svg
et dessiner sur la toile en utilisant.drawImage()
:
- faire un élément de toile
- fabriquer un objet svgBlob à partir du xml svg
- fabriquer un objet url à partir de domUrl.createObjectURL(svgBlob) ;
- créer un objet Image et assigner l'url à l'image src
- dessiner une image dans le canevas
- récupérer la chaîne de données png du canevas : canvas.toDataURL() ;
Belle description : https://web.archive.org/web/20200125162931/http://ramblings.mcpher.com:80/Home/excelquirks/gassnips/svgtopng
Notez que dans IE, vous obtiendrez une exception à l'étape de canvas.toDataURL() ; C'est parce que IE a une restriction de sécurité trop élevée et traite le canvas comme readonly après y avoir dessiné l'image. Tous les autres navigateurs n'imposent des restrictions que si l'image a une origine croisée.
- Utilisez
canvg
bibliothèque JavaScript. Il s'agit d'une bibliothèque distincte mais qui possède des fonctions utiles.
Comme :
ctx.drawSvg(rawSvg);
var dataURL = canvas.toDataURL();
J'ai récemment découvert quelques bibliothèques de traçage d'images pour JavaScript qui sont effectivement capables de construire une approximation acceptable du bitmap, tant en taille qu'en qualité. Je suis en train de développer cette bibliothèque JavaScript et le CLI :
https://www.npmjs.com/package/svg-png-converter
Ce qui fournit une API unifiée pour tous ces éléments, supportant le navigateur et le nœud, ne dépendant pas du DOM, et un outil de ligne de commande.
Pour convertir des logos, des dessins animés ou des images similaires, il fait un excellent travail. Pour les photos / le réalisme, il est nécessaire de faire quelques ajustements car la taille de la sortie peut augmenter considérablement.
Il dispose d'un terrain de jeu, mais je travaille actuellement sur un meilleur terrain, plus facile à utiliser, puisque de nouvelles fonctionnalités ont été ajoutées :
https://cancerberosgx.github.io/demos/svg-png-converter/playground/#
0 votes
Quelle est la tâche que vous voulez réellement accomplir ? Même si la réponse des flux d'écho nous dit que c'est (dans certains navigateurs) possible, il existe des méthodes de conversion meilleures et plus faciles pour presque tous les cas pratiques.
2 votes
Voici un exemple utilisant d3 : stackoverflow.com/a/23667012/439699
0 votes
svgopen.org/2010/papers/62-From_SVG_to_Canvas_and_Back - Fonctionne parfaitement ! [Sur la page du lien, sourceSVG = $("#votre_svg_elem_name").get(0) ]
0 votes
Liés : stackoverflow.com/questions/3173048/
0 votes
mybyways.com/blog/convert-svg-to-png-using-your-browser
0 votes
Cela répond-il à votre question ? Capturez le canevas HTML en gif/jpg/png/pdf ?