2010-10-20 10 views
236

Je veux convertir SVG en images bitmap (comme JPEG, PNG, etc.) via JavaScript.Convertir SVG en image (JPEG, PNG, etc.) dans le navigateur

+0

Quelle tâche est-ce que vous voulez réellement accomplir? Même si les échos-réponses nous disent que c'est (dans certains navigateurs) possible, il existe des méthodes de conversion meilleures et plus faciles pour presque tous les cas pratiques. – aaaaaaaaaaaa

+2

Voici un exemple utilisant d3: http://stackoverflow.com/a/23667012/439699 – ace

+0

http://svgopen.org/2010/papers/62-From_SVG_to_Canvas_and_Back/ - Fonctionne parfaitement! [Sur la page de liens, sourceSVG = $ ("# your_svg_elem_name"). Get (0)] –

Répondre

197

Voici comment vous pouvez le faire via JavaScript:

  1. Utilisez la canvg bibliothèque JavaScript pour rendre l'image SVG utilisant Canvas: https://github.com/gabelerner/canvg
  2. capture une URI données codées en format JPG (ou PNG) de le Canvas, selon ces instructions: Capture HTML Canvas as gif/jpg/png/pdf?
+26

Ce n'est pas strictement Javascript, mais HTML5 aussi bien. Cela ne fonctionnera pas sur IE8 ou tout autre navigateur qui ne prend pas en charge HTML5 Canvas. – James

+10

Si le navigateur supporte SVG et canvas, alors il y aurait un moyen beaucoup plus simple de charger le SVG en mémoire et de le peindre dans un canvas, sans avoir besoin de Canvg, qui est une bibliothèque assez volumineuse car elle gère tout l'analyse SVG qu'un navigateur SVG-support fournit déjà gratuitement.Je ne suis pas sûr si cela satisfait le cas d'utilisation d'origine, mais si c'est le cas, alors [voir cette ressource pour plus de détails] (https://svgopen.org/2010/papers/62-From_SVG_to_Canvas_and_Back/index.html). – Premasagar

+72

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

-1

Si vous ne voulez pas dire par programme, cette question devrait probablement appartenir à superuser.com.

De toute façon, le Batik SVG Toolkit peut être utile, en particulier le SVG Rasterizer.

+5

Je veux le convertir en javascript – Zain

+1

@ fish2000 non vous avez toujours raison. Si vous voulez supporter IE8, votre seule vraie solution est de sérialiser le SVG et de l'envoyer à un Rasterizer SVG de Batik côté serveur. – James

+2

@James sympa, il est toujours bon de rester à l'affût de l'absence décisive des caractéristiques du nouveau manque d'innovations d'IE {8,9, x}. THX. – fish2000

37

La solution jbeard4 a fonctionné magnifiquement. J'utilise Raphael SketchPad pour créer un fichier SVG. Lien vers les fichiers à l'étape 1.

Pour un bouton Enregistrer (id svg est « éditeur », id de toile est « toile »):

$("#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

canvg besoin du second paramètre à être ' ... '+ $ ("# editor"). Html() +' '); ' – Luckyn

+1

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

+0

@Luckyn et @jonathanGB, vous ne devriez pas avoir à utiliser 'html()' sur des wrappers, ou à construire manuellement la balise 'svg' parent - qui pourrait même avoir des attributs que vous omettez avec ce hack. Utilisez simplement '$ (svg_elem) [0] .outerHTML' vous donne la source complète du svg et de son contenu. Juste en disant ... – nemesisfixx

2

est ici une solution côté serveur basé sur PhantomJS. Vous pouvez utiliser JSONP pour faire un appel inter-domaine au service de l'image:

https://github.com/vidalab/banquo-server

Par exemple:

http://[host]/api/https%3A%2F%2Fvida.io%2Fdocuments%2FWgBMc4zDWF7YpqXGR/viewport_width=980&viewport_height=900&delay=5000&selector=%23canvas

Ensuite, vous pouvez afficher l'image avec tag img:

<img src="data:image/png;base64, [base64 data]"/> 

Cela fonctionne à travers le navigateur.

+0

Le service semble être mort. – Tibor

+2

Notre hôte avait été frappé avec des demandes fausses. Nous avons donc décidé de l'abattre. Vous devrez exécuter votre propre serveur maintenant. Voir le repo de github pour plus d'informations. –

2

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