Forums : Xul, Xbl, JS...

Aller à la discussion :  Plus récente Plus ancienne

# [Résolu] sauvegarde d'un graphique svg en un png avec transparence

Envoyé par : mothsart

Date : 28/03/2010 15:18

Bonjour,

j'ai créé une petite application me permettant de modifier des fichiers svg en incluant des images. Une fois que le graphique est concluant, l'utilisateur peut enregistrer son image sous la forme d'un png.

Ceci est effectué grâce à un "canvas" transparent positionné par dessus le graphique SVG. Le tout est assez fonctionnel.

Seul petit bémol : J'aimerais que mon image png ne prenne pas en compte le fond de mon application mais garde la transparence de mon svg... Est-ce réalisable?

Voici le code concerné : code

 function saveCanvas(canvas,destFile){
   // convert string filepath to an nsIFile
   var file = Components.classes["@mozilla.org/file/local;1"]
           .createInstance(Components.interfaces.nsILocalFile);
   file.initWithPath(destFile);
   // create a data url from the canvas and then create URIs of the source and targets
   var io = Components.classes["@mozilla.org/network/io-service;1"]
           .getService(Components.interfaces.nsIIOService);
   var source = io.newURI(canvas.toDataURL("image/png", ""), "UTF8", null);
           var target = io.newFileURI(file)
   // prepare to save the canvas data
   var persist = Components.classes["@mozilla.org/embedding/browser/nsWebBrowserPersist;1"]
           .createInstance(Components.interfaces.nsIWebBrowserPersist);
   persist.persistFlags = Components.interfaces.nsIWebBrowserPersist.PERSIST_FLAGS_REPLACE_EXISTING_FILES;
   persist.persistFlags |= Components.interfaces.nsIWebBrowserPersist.PERSIST_FLAGS_AUTODETECT_APPLY_CONVERSION;
   // save the canvas data to the file
   persist.saveURI(source, null, null, null, null, file);
 }
 var ctx = document.getElementById('canvas').getContext('2d');
 var frame = document.getElementById('frame').getBBox();
 var frame_preview = this.boxObject;
 var left = frame_preview.x;
 var top = frame_preview.y;
 var width = document.getElementById('canvas').width;
 var height = document.getElementById('canvas').height;
 ctx.drawWindow(window,left,top,width,height,"rgba(0,0,0,0)");
 saveCanvas(document.getElementById('canvas'),url);

# Re: sauvegarde d'un graphique svg en un png avec transparence

Envoyé par : laurentj

Date : 29/03/2010 15:45

Ceci est effectué grâce à un "canvas" transparent positionné par dessus le graphique SVG

Ton canvas n'a absolument pas besoin d'être au dessus, il peut même être caché.

Et sinon, je sais pas ce qu'est ton getBBox, ni ton this.boxObject. il faut récupérer le boxObject de l'element que tu veux "photographier".

Une variante que j'ai fait dans un projet (même si j'ai pas vérifié si j'avais bien un fond transparent):

         // boxobject de ce que je veux photographier
         let box = maboxXUL.boxObject;
         // mon element canvas, quelque part caché dans mon document
         let canvas = moncanvas;
 
         let w = box.width;
         let h = box.height;

         // mon canvas va avoir la même taille que mon element à photographier
         canvas.style.width = w + "px";
         canvas.style.height = h + "px";
         canvas.width = w;
         canvas.height = h;

         let ctx = canvas.getContext("2d");
         ctx.clearRect(0, 0, w, h);
         ctx.drawWindow(window, box.x, box.y, w, h, "rgba(0,0,0,0)");

# Re: sauvegarde d'un graphique svg en un png avec transparence

Envoyé par : mothsart

Date : 29/03/2010 16:53

mon exemple de code est contenu dans un xbl donc le this fait référence à lui. C'est bien lui que je veux photographier. Seulement, il n'y a aucune association entre le canvas et cette boite. (à part les dimensions) Du coup, le canvas photographie le svg mais également le fond de mon appli xul. (marron par défaut ;)) Est-ce qu'il y a une astuce pour contourner ça?

# Re: sauvegarde d'un graphique svg en un png avec transparence

Envoyé par : mothsart

Date : 07/04/2010 17:53

J'ai finalement trouvé une astuce : utiliser une iframe contenant mon svg. Pour obtenir la transparence, je n'ai pas appliqué les css "//global/skin/" (j'ai pas cherché exactement d'où ça provenait...) Enfin, j'associe mon iframe à mon canvas :

ctx.drawWindow(iframe.contentWindow, box.x, box.y, w, h, "rgba(0,0,0,0)");

Il n'est plus possible de poster des messages dans ce forum.


Copyright © 2003-2013 association xulfr, 2013-2016 Laurent Jouanneau - Informations légales.

Mozilla® est une marque déposée de la fondation Mozilla.
Mozilla.org™, Firefox™, Thunderbird™, Mozilla Suite™ et XUL™ sont des marques de la fondation Mozilla.