Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
2566 connectés 

  FORUM HardWare.fr
  Programmation
  Java

  Utiliser un Canvas pour dessiner dedant, et générer une Image

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

Utiliser un Canvas pour dessiner dedant, et générer une Image

n°419579
El_gringo
Posté le 06-06-2003 à 15:35:15  profilanswer
 

Utiliser un Canvas pour dessiner dedant, et générer une BufferedImage, tout ceci sans l'afficher, jamais, ça vous choque ?
 
EDIT : en fait si ça se trouve, ça sert même à ça un Canvas, j'en sais rien, je n'ai jamais fait d'interface en Java (ni AWT, ni Swing).


Message édité par El_gringo le 06-06-2003 à 15:38:24
mood
Publicité
Posté le 06-06-2003 à 15:35:15  profilanswer
 

n°419587
LetoII
Le dormeur doit se réveiller
Posté le 06-06-2003 à 15:40:04  profilanswer
 

Heu ben j'ai pas de réponse mais je suis intéressé :D [:blueflag]


---------------
Le Tyran
n°419634
gfive
Posté le 06-06-2003 à 15:57:38  profilanswer
 

On peut le faire...mais il te faudra quand même un élément graphique affiché pour récupérer un contexte graphiquye valide, sinon, pas moyen....
 
En gros :  
 

Code :
  1. Canvas c = new Canvas();
  2. Image i = c.createImage(width, height);

 
 
Te donne une image nulle, si c n'est pas affiché....
 
Donc, si tu fais ça :  
 
 
 

Code :
  1. public class Test {
  2.     public static void main(String[] args) {
  3.         Frame f = new Frame();
  4.         Canvas c2 = new Canvas();
  5.         c2.setSize(new Dimension(200, 200));
  6.         f.add(c2);
  7.         f.pack();
  8.         f.show();
  9.         Canvas c = new Canvas();
  10.         c.setSize(new Dimension(200, 200));
  11.         Image i = c2.createImage(200, 200);
  12.         System.out.println(i);
  13.         Graphics g = i.getGraphics();
  14.         g.setColor(Color.red);
  15.         g.fillRect(50, 50, 100, 100);
  16.        
  17.     }

 
 
tu peux dessiner dans g, sans que i soit jamais affichée....Par contre, si tu enlèves le premier "paragraphe" de code, et que tu fais Image i = c.createImage(..) au lieu de Image i = c2.createImage()
 
ben tu te prendra une NullPointerException au moment du getGraphics.
 
Je sais, c'est pas clair!! :D

n°419683
El_gringo
Posté le 06-06-2003 à 16:09:07  profilanswer
 

gfive a écrit :


Je sais, c'est pas clair!! :D


 
Je crois. ça veut dire que, si je comptais faire ça dans une appli-web, côté serveur, c'est grillé, non ?
Parce que ça risque d'être un joyeux bordel sur le serveur...

n°419690
El_gringo
Posté le 06-06-2003 à 16:10:19  profilanswer
 

LetoII a écrit :

Heu ben j'ai pas de réponse mais je suis intéressé :D [:blueflag]  


 
T'as compris que ça découlair de l'autre topic que j'ai lancé:
http://forum.hardware.fr/forum2.ph [...] h=&subcat=

n°419706
LetoII
Le dormeur doit se réveiller
Posté le 06-06-2003 à 16:14:55  profilanswer
 

El_gringo a écrit :


 
T'as compris que ça découlair de l'autre topic que j'ai lancé:
http://forum.hardware.fr/forum2.ph [...] h=&subcat=


 
non non  :sarcastic:


---------------
Le Tyran
n°419752
gfive
Posté le 06-06-2003 à 16:24:13  profilanswer
 

En fait, on peut le faire :  
 
comme ça :  
 
 

Code :
  1. public class Test {
  2.     public static void main(String[] args) {
  3.         Image i = new BufferedImage(200, 200, BufferedImage.TYPE_INT_RGB);
  4.         Graphics g = i.getGraphics();
  5.         g.setColor(Color.red);
  6.         g.fillRect(50, 50, 100, 100);
  7. }

 
 
et là, tu as une image qui va bien, il te reste plus qu'à la sauver dans un fichier, ou en faire ce que tu veux..
Mais attention : si tu utilises un jdk < 1.4, et linux (ou unix) ça nécessitera d'installer X sur ton serveur.
 
Si tu utilises un jdk >= 1.4, en lancant ton appli avec l'option -Dheadless=true (ou qqchose comem ça) tu n'a pas besoin de X. En plus, avec la nouvelle API javax.imageio, tu pourra sauver ton image dans un fichier beaucoup plus facilement....
 
J'ai un autre exemple :  
 
 

Code :
  1. public void generateMap(File sourceFile, ArrayList tokens, String targetfile) throws AtchikException {
  2.  try {
  3.     BufferedImage source = ImageIO.read(sourceFile);
  4.      BufferedImage image = new BufferedImage(source.getWidth(),
  5.           source.getHeight(),
  6.           BufferedImage.TYPE_INT_RGB);
  7.      Graphics2D g = image.createGraphics();
  8.    
  9.      g.drawImage(source, 0, 0, g.getColor(), null);
  10.    
  11.      Iterator it = tokens.iterator();
  12.      while (it.hasNext()) {
  13.   ((WeatherMapToken) it.next()).draw(g);
  14.      }
  15.      File f = new File(targetfile);
  16.     if (extension.equalsIgnoreCase(".gif" )) {
  17.  try {
  18.      GIFEncoder encoder = new GIFEncoder(image);
  19.      encoder.Write(new FileOutputStream(f));
  20.  } catch (AWTException awt) {
  21.      Debug.err(awt);
  22.  }
  23.     } else if (extension.equalsIgnoreCase(".jpg" )) {
  24.  ImageIO.write(image, "JPG", f);
  25.     } else {
  26.  throw new AtchikException("[MapGenerator.generateMap] Cannot prepare "+extension+" images" );
  27.     }
  28.  } catch (IllegalArgumentException iae) {
  29.      Debug.err(iae);
  30.      throw new AtchikException(iae.toString());
  31.  } catch (IOException ioe) {
  32.      Debug.err(ioe);
  33.      throw new AtchikException(ioe.toString());
  34.  }
  35.      }

 
 
bon, je te détaille pas le code, mais en gros, ça dessine des objets (les Tokens) sur une image de fond (source), en utilisant la méthode draw(Graphics g) de chaque Token,  et ça sauve le résultat dans le fichier f, en GIF, en utilisant un GIFEncoder, qui est une librairie trouvée sur le net.

n°419767
El_gringo
Posté le 06-06-2003 à 16:27:29  profilanswer
 

LetoII a écrit :


non non  :sarcastic:  


 
Ho, ça va, c'était juste un moyen de caser un petit lien vers mon autre topic! :o

n°419779
LetoII
Le dormeur doit se réveiller
Posté le 06-06-2003 à 16:31:27  profilanswer
 

El_gringo a écrit :


 
Ho, ça va, c'était juste un moyen de caser un petit lien vers mon autre topic! :o  


 
 :lol:


---------------
Le Tyran
n°419786
El_gringo
Posté le 06-06-2003 à 16:35:32  profilanswer
 

gfive a écrit :

En fait, on peut le faire :  
 
comme ça :  
 
 

Code :
  1. public class Test {
  2.     public static void main(String[] args) {
  3.         Image i = new BufferedImage(200, 200, BufferedImage.TYPE_INT_RGB);
  4.         Graphics g = i.getGraphics();
  5.         g.setColor(Color.red);
  6.         g.fillRect(50, 50, 100, 100);
  7. }

 
 
et là, tu as une image qui va bien, il te reste plus qu'à la sauver dans un fichier, ou en faire ce que tu veux..
Mais attention : si tu utilises un jdk < 1.4, et linux (ou unix) ça nécessitera d'installer X sur ton serveur.
 
Si tu utilises un jdk >= 1.4, en lancant ton appli avec l'option -Dheadless=true (ou qqchose comem ça) tu n'a pas besoin de X. En plus, avec la nouvelle API javax.imageio, tu pourra sauver ton image dans un fichier beaucoup plus facilement....
 
J'ai un autre exemple :  
 
 

Code :
  1. public void generateMap(File sourceFile, ArrayList tokens, String targetfile) throws AtchikException {
  2.  try {
  3.     BufferedImage source = ImageIO.read(sourceFile);
  4.      BufferedImage image = new BufferedImage(source.getWidth(),
  5.           source.getHeight(),
  6.           BufferedImage.TYPE_INT_RGB);
  7.      Graphics2D g = image.createGraphics();
  8.    
  9.      g.drawImage(source, 0, 0, g.getColor(), null);
  10.    
  11.      Iterator it = tokens.iterator();
  12.      while (it.hasNext()) {
  13.   ((WeatherMapToken) it.next()).draw(g);
  14.      }
  15.      File f = new File(targetfile);
  16.     if (extension.equalsIgnoreCase(".gif" )) {
  17.  try {
  18.      GIFEncoder encoder = new GIFEncoder(image);
  19.      encoder.Write(new FileOutputStream(f));
  20.  } catch (AWTException awt) {
  21.      Debug.err(awt);
  22.  }
  23.     } else if (extension.equalsIgnoreCase(".jpg" )) {
  24.  ImageIO.write(image, "JPG", f);
  25.     } else {
  26.  throw new AtchikException("[MapGenerator.generateMap] Cannot prepare "+extension+" images" );
  27.     }
  28.  } catch (IllegalArgumentException iae) {
  29.      Debug.err(iae);
  30.      throw new AtchikException(iae.toString());
  31.  } catch (IOException ioe) {
  32.      Debug.err(ioe);
  33.      throw new AtchikException(ioe.toString());
  34.  }
  35.      }

 
 
bon, je te détaille pas le code, mais en gros, ça dessine des objets (les Tokens) sur une image de fond (source), en utilisant la méthode draw(Graphics g) de chaque Token,  et ça sauve le résultat dans le fichier f, en GIF, en utilisant un GIFEncoder, qui est une librairie trouvée sur le net.


 
Cool.
Là tu remet en question ce que tu disais au début, non !?
Pour la sauvegarde par contre, c'est bon. Je sauvegarde pas mes images, je les converti en tel ou tel format, les dimensionne correctement, les oriente correctement, et puis je les balances sur la sortie HTTP d'une servlet. ça, c'est déja géré avec des images générées plus "normalement" (simplement lues dans un fichier).
Merci...

mood
Publicité
Posté le 06-06-2003 à 16:35:32  profilanswer
 

n°419802
gfive
Posté le 06-06-2003 à 16:38:32  profilanswer
 

ouais, je me remet en question, effectivement!! :D
J'avais oublié que j'avais fait ce machin truc... :p Ca fait plus d'un an, alors bon... :D

n°419850
El_gringo
Posté le 06-06-2003 à 16:45:14  profilanswer
 

Ha, mais par contre, là tu n'utilises pas de Canvas.
En fait, voila pourquoi je veux faire ça :
j'ai une image générée en C++ par JNI, et je voudrais en récupérer une BufferedImage. Le format "standard" d'images en C/C++, sous windows, et voila le code d'exmple que j'ai trouvé:

Code :
  1. /*
  2. * AWT Native Drawing Surface (JAWT_DrawingSurface).
  3. *
  4. * For each platform, there is a native drawing surface structure.  This
  5. * platform-specific structure can be found in jawt_md.h.  It is recommended
  6. * that additional platforms follow the same model.  It is also recommended
  7. * that VMs on Win32 and Solaris support the existing structures in jawt_md.h.
  8. *
  9. *******************
  10. * EXAMPLE OF USAGE:
  11. *******************
  12. *
  13. * In Win32, a programmer wishes to access the HWND of a canvas to perform
  14. * native rendering into it.  The programmer has declared the paint() method
  15. * for their canvas subclass to be native:
  16. *
  17. *
  18. * MyCanvas.java:
  19. */
  20. import java.awt.*;
  21. public class MyCanvas extends Canvas {
  22.      static {
  23.          System.loadLibrary("mylib" );
  24.      }
  25.      public native void paint(Graphics g);
  26. }
  27. /*************************************
  28. * myfile.c:
  29. */
  30. #include "jawt_md.h"
  31. #include <assert.h>
  32. JNIEXPORT void JNICALL
  33. Java_MyCanvas_paint(JNIEnv* env, jobject canvas, jobject graphics)
  34. {
  35.      JAWT awt;
  36.      JAWT_DrawingSurface* ds;
  37.      JAWT_DrawingSurfaceInfo* dsi;
  38.      JAWT_Win32DrawingSurfaceInfo* dsi_win;
  39.      jboolean result;
  40.      jint lock;
  41.      // Get the AWT
  42.      awt.version = JAWT_VERSION_1_3;
  43.      result = JAWT_GetAWT(env, &awt);
  44.      assert(result != JNI_FALSE);
  45.      // Get the drawing surface
  46.      ds = awt.GetDrawingSurface(env, canvas);
  47.      assert(ds != NULL);
  48.      // Lock the drawing surface
  49.      lock = ds->Lock(ds);
  50.      assert((lock & JAWT_LOCK_ERROR) == 0);
  51.      // Get the drawing surface info
  52.      dsi = ds->GetDrawingSurfaceInfo(ds);
  53.      // Get the platform-specific drawing info
  54.      dsi_win = (JAWT_Win32DrawingSurfaceInfo*)dsi->platformInfo;
  55.      //////////////////////////////
  56.      // !!! DO PAINTING HERE !!! //
  57.      //////////////////////////////
  58.      // Free the drawing surface info
  59.      ds->FreeDrawingSurfaceInfo(dsi);
  60.      // Unlock the drawing surface
  61.      ds->Unlock(ds);
  62.      // Free the drawing surface
  63.      awt.FreeDrawingSurface(ds);
  64. }

n°419857
gfive
Posté le 06-06-2003 à 16:46:55  profilanswer
 

bah, a ce moment là, tu modifies ça, pour te passer du Canvas, et tu utilises directement le Graphics, plutôt.....

n°419899
El_gringo
Posté le 06-06-2003 à 16:56:50  profilanswer
 

gfive a écrit :

bah, a ce moment là, tu modifies ça, pour te passer du Canvas, et tu utilises directement le Graphics, plutôt.....


 
Ben oui, j'suis bête moi.
C'est génial, je vais faire des trucs extraordinaires! :D  
Merci beaucoup.
 
EDIT : la Java est un langage génial ! :D


Message édité par El_gringo le 06-06-2003 à 16:57:19
n°423475
El_gringo
Posté le 11-06-2003 à 09:47:13  profilanswer
 

gfive a écrit :

bah, a ce moment là, tu modifies ça, pour te passer du Canvas, et tu utilises directement le Graphics, plutôt.....


 
Hé ben non, apparement, c'est n'est pas possible (ou alors je n'vois pas comment): pour faire ce que je veux, j'ai besoin d'une structure "JAWT_DrawingSurface" valide. Chose que je n'peux obtenir qu'en utilisant "GetDrawingSurface", qui prend pour paramètre un java.awt.Component.
Donc, j'en reviens à la question de départ ( :sweat: ):  
Je voudrais dessiner dans un Canvas, puis obtenir une BufferedImage de ce qui y à été dessiné. Tout ça, sans afficher ce fameux Canvas !
ça vous parait possible ? Comment ?

n°423810
gfive
Posté le 11-06-2003 à 13:52:22  profilanswer
 

baaaah...Tupeux instancier un Canvas sans l'afficher, hein...Mais tu aura toujours le problème qu'avec un JDK < 1.4, tu ne pourra pas obtenir une instance de Graphics à partir de ce machin là.....

n°423890
El_gringo
Posté le 11-06-2003 à 14:29:05  profilanswer
 

gfive a écrit :

baaaah...Tupeux instancier un Canvas sans l'afficher, hein...Mais tu aura toujours le problème qu'avec un JDK < 1.4, tu ne pourra pas obtenir une instance de Graphics à partir de ce machin là.....


 
C'est pas grave, regarde la méthode que j'ai postée : ils n'utilisent pas l'instance de Graphics. Elle est là juste pour correcpondre à la signature, parce qu'ils veulent redéfinir la méthode "paint" de leur Component. Moi, étant donne que c'est juste pour enregistrer une image (et non l'afficher), je pourrait me faire une autre méthode native (genre createJNIImage), sans paramètres, dans laquelle je ferait exactement la même chose que ce qu'ils font.
Reste à trouver comment obtenir un BufferedImage représentant le contenu de ce Canvas...

n°424651
El_gringo
Posté le 12-06-2003 à 08:56:30  profilanswer
 

Pas sur que ce soit des masses utile, mais je tente quand même un petit retour de topic...

n°424706
gfive
Posté le 12-06-2003 à 09:59:23  profilanswer
 

Et en faisant ça :  
 

Code :
  1. Canvas tonCanvas = new Canvas();
  2.   // dessin en natif
  3. Image i = new BufferedImage(200, 200, BufferedImage.TYPE_INT_RGB);
  4. Graphics g = i.getGraphics();
  5.  
  6.   tonCanvas.paint(g);

 
 
ça suffirait pas???

n°424762
El_gringo
Posté le 12-06-2003 à 10:57:48  profilanswer
 

gfive a écrit :

Et en faisant ça :  
 

Code :
  1. Canvas tonCanvas = new Canvas();
  2.   // dessin en natif
  3. Image i = new BufferedImage(200, 200, BufferedImage.TYPE_INT_RGB);
  4. Graphics g = i.getGraphics();
  5.  
  6.   tonCanvas.paint(g);

 
 
ça suffirait pas???


 
Heu, je sais pas vraiment.
Après avoir fait ça, mon Image i contient ce que j'ai dessiné dedant via la méthode paint ?

n°424938
gfive
Posté le 12-06-2003 à 13:13:25  profilanswer
 

Si t'as dessiné dedant, non.. Mais si t'as dessiné dedans, oui!! :D:D


Message édité par gfive le 12-06-2003 à 13:16:50
n°425050
El_gringo
Posté le 12-06-2003 à 14:13:01  profilanswer
 

gfive a écrit :

Si t'as dessiné dedant, non.. Mais si t'as dessiné dedans, oui!! :D:D


 
Heu, y aurait pas comme une erreur dans ce que t'as écrit là !? :??:  
Et moi j'reprend ce que j'ai dit :
Avec ce que tu m'a donné un p'tit peu au dessus, mon Image i contient ce que je dessine via la méthode paint ?

n°425107
gfive
Posté le 12-06-2003 à 14:47:15  profilanswer
 

Je te faisais juste remarquer que dedans prend un S à la fin, c'est tout!! :D:D
Mais sinon, oui, ça devrait marcher.
 
(Mais dans le bout de code que j'avais mis, te n'aura normalement pas à mettre de code à l'endroit où j'ai mis "//ton code en natif" parce que c'est fait par l'appel à tonCanvas.paint(g);
 
ouala.

n°425128
El_gringo
Posté le 12-06-2003 à 15:00:05  profilanswer
 

Ok, merci pour tout.
Dans l'immédiat, j'n'ai pas le temps d'essayer ça, mais dès que j'en saurais plus, je posterai ici pour dire ce qu'il en est bien sur. :hello:

n°425131
gfive
Posté le 12-06-2003 à 15:02:17  profilanswer
 

ouais, ça m'intéresse, la partie en natif C!! :)

n°427522
R3g
fonctionnaire certifié ITIL
Posté le 14-06-2003 à 13:21:57  profilanswer
 

Juste un truc : je suis pas sur d'avoir bien tout compris, mais pour dessiner en win32, tu vas avoir besoin du HWND du composant, l'handle de sa fenetre ; et si le composant n'est pas affiché, pas de handle de fenetre. Je me trompe ?

n°428836
El_gringo
Posté le 16-06-2003 à 10:50:18  profilanswer
 

R3g a écrit :

Juste un truc : je suis pas sur d'avoir bien tout compris, mais pour dessiner en win32, tu vas avoir besoin du HWND du composant, l'handle de sa fenetre ; et si le composant n'est pas affiché, pas de handle de fenetre. Je me trompe ?


 
Pas besoin de HWND pour dessiner en Win32. Un Device Context (DC) suffira.

n°436168
LetoII
Le dormeur doit se réveiller
Posté le 23-06-2003 à 09:04:15  profilanswer
 

El_gringo a écrit :


 
Pas besoin de HWND pour dessiner en Win32. Un Device Context (DC) suffira.


 
Arréte moi si je me trompe, ton DC tu le récupère pas à partir d'un Handle? (Ca fait un moment que j'ai pas utilisé ça j'ai un trou de mémoire :D)


---------------
Le Tyran
n°436172
El_gringo
Posté le 23-06-2003 à 09:07:35  profilanswer
 

LetoII a écrit :


 
Arréte moi si je me trompe, ton DC tu le récupère pas à partir d'un Handle? (Ca fait un moment que j'ai pas utilisé ça j'ai un trou de mémoire :D)


 
Si on veut dessiner dans une vue (ou un autre élément graphique), si, bien sur, il faut récupérer le DC à partir du handle de la fenêtre dans laquelle on veut dessiner. Mais on peut très bien utiliser un DC "virtuel" pour dessiner en mémoire seulement.

mood
Publicité
Posté le   profilanswer
 


Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  Java

  Utiliser un Canvas pour dessiner dedant, et générer une Image

 

Sujets relatifs
JNI - Obtenir une image Java à partir d'une image Windowsgenerer du swf
Détecter des lignes sur une imageTraitement d'image (contrôle image) sous VBA Excel
Access et les Autonumbers.... => Comment les générer à la main[PHP] Comment inserer une image en php ?
[PHP - MYSQL] Sauvegarder uen image dans un champ de la bd[Java/Algo] Reconnaitre un disque dans un image
[Perl] Utiliser le module Net::Telnet sans l'avoir installéBesoin d'aide [Générer un permutoèdre]
Plus de sujets relatifs à : Utiliser un Canvas pour dessiner dedant, et générer une Image


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR