388 votes

Convertir SVG en image (JPEG, PNG, etc.) dans le navigateur

Je veux convertir SVG en images bitmap (comme JPEG, PNG, etc.) via JavaScript.

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) ]

282voto

jbeard4 Points 5680

Voici comment vous pouvez le faire par le biais de JavaScript :

  1. Utilisez la bibliothèque JavaScript canvg pour rendre l'image SVG à l'aide de Canvas : https://github.com/gabelerner/canvg
  2. Capturez un URI de données encodé sous forme de JPG (ou PNG) à partir du Canvas, en suivant ces instructions : Capturez le canevas HTML en gif/jpg/png/pdf ?

31 votes

Il ne s'agit pas strictement de Javascript, mais aussi de HTML5. Cela ne fonctionnera pas sur IE8, ou tout autre navigateur qui ne supporte pas HTML5 Canvas.

16 votes

Si le navigateur supporte le SVG et le canvas, alors il y aurait un moyen beaucoup plus simple de charger le SVG en mémoire et ensuite de le peindre sur un canvas, sans avoir besoin de Canvg, qui est une bibliothèque assez grande parce qu'elle gère tout le parsing SVG qu'un navigateur supportant le SVG fournit déjà gratuitement. Je ne suis pas sûr que cela satisfasse le cas d'utilisation original, mais si oui, alors voir cette ressource pour plus de détails .

192 votes

Merci de ne pas supporter IE8. Les gens devraient comprendre qu'il est temps de passer à autre chose.

48voto

coop Points 338

La solution de jbeard4 a fonctionné à merveille.

J'utilise Raphael SketchPad pour créer un SVG. Lien vers les fichiers de l'étape 1.

Pour un bouton Enregistrer (id du svg est "editor", id du 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...
});

1 votes

Canvg a besoin que le second paramètre soit <svg>...</svg mais la fonction jquery html() n'ajoute pas la balise svg, donc ce code fonctionne pour moi mais j'ai eu besoin de modifier le canvg live en canvg('canvas', '<svg>'+$("#editor").html()+'</svg>');

1 votes

@Luckyn si vous appelez $(selector).html() sur le parent de votre svg l'élément, il fonctionnera

1 votes

@Luckyn et @jonathanGB, vous ne devriez pas avoir à utiliser html() sur les wrappers, ou construire manuellement le parent svg qui peut même avoir des attributs que vous pouvez laisser de côté avec cette astuce. Utilisez simplement $(svg_elem)[0].outerHTML vous donne la source complète du svg et de son contenu. Je dis ça comme ça...

36voto

worstenbrood Points 247

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;
}

31voto

Thom Kiesewetter Points 653

La solution pour convertir SVG en URL de type blob et URL de type 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;
 }

11voto

Mahdi Khalili Points 79

Changement 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()

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X