IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

2D Java Discussion :

Paint en java


Sujet :

2D Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti Avatar de mathieumadrid
    Étudiant
    Inscrit en
    Juin 2005
    Messages
    39
    Détails du profil
    Informations personnelles :
    Âge : 39

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2005
    Messages : 39
    Par défaut Paint en java
    Bonjour à tous,

    Je suis en train de faire une sorte de Paint avec java. J'applique le modèle MVC. Le coeur de ma petite application est un cadre (Cadre.java). Dans ce cadre se trouve un tableau de Color[][] qui représentent chaque pixel d'une image. Une vue (VueCadre.java) surveille en permanence ce cadre. C'est à dire qu'à chaque fois qu'un pixel change dans le cadre, il est affiché dans la vue. Ensuite, à partir du cadre, je peux dessiner (sans utiliser les classes prédéfinies de java.awt comme Graphics ou Graphics2D). C'est de là que vient mon premier souci. En effet, lorsque je dessine par exemple des rectangles ou des ellipses, java met beaucoup de temps à les dessiner. Est-ce du au fait que mon image soit sans arrêt redessiner lorsqu'un pixel change dans le cadre ?
    Dans VueCadre.java, j'ai:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    public void update(Observable obs, Object obj)
    {
    	...
    	g = getGraphics();
    	x = cadre.getX(); // Retourne la position de la souris dans le cadre
    	y = cadre.getY(); // Pareil
    	Outils.drawPixel(g,x,y,cadre.getPixel(x,y)); // Dessine seulement le pixel modifié dans le JPanel
    	...
    }
    Sinon, mon application gère aussi la sauvegarde et l'ouverture de fichiers du type *.draw (format personnel), *.bmp (sans table de couleurs) et *.pgm (images à nuances de gris). Quand j'ouvre par exemple une image 200x200, je n'ai pas de soucis (sauf qu'elle met un peu de temps à s'ouvrir) mais si je veux ouvrir une image *.bmp de dimension 1100x1500 alors je suis obligé d'augmenter la mémoire vive de JVM (Xmx128m au lieu de Xmx64m). Je voudrais résoudre ce problème. J'ai remarqué que ce problème venait de ma classe IO.java (classe statique qui regroupe mes fonctions d'E/S). C'est quand je retourne une couleur (new Color(...)) à chaque fois que je lis un pixel dans une image *.bmp :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
     
    public static Color readBMPColor(DataInputStream stream)
    {
    	int r, g, b;
    	r = g = b = 255;
    	byte[] octets = new byte[3];
     
    	try
    	{
    		stream.read(octets);
    		b = octets[0] & MASK; // avec MASK = 0xFF
    		g = octets[1] & MASK;
    		r = octets[2] & MASK;
    	}
    	catch(IOException ex){}
     
    	return new Color(r,g,b);
    }
    En résumé, je voudrais améliorer la vitesse d'exécution de mon application. Je pense que cette lenteur vient de mon code (peut-être mal codé). Auriez-vous des idées pour optimiser un peu mon code ?

    PS : Mon application n'est pas très volumineuse. Vous pouvez la télécharger ici draw.zip. Les classes on été compilées avec la version 1.6 de java. Pour lancer l'application, faites ./draw.csh (si vous avez linux ou cygwin avec csh) ou java draw/graphique/Draw &. Vous trouverez également la doc dans le fichier *.zip.

    Merci de votre aide.

  2. #2
    Membre éprouvé
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    116
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2007
    Messages : 116
    Par défaut
    Salut, evidemment que c'est long avec un tableau de Color (compte un peu le nombre d'objets couleurs que doit mettre en memoire ta jvm)
    Commence par enregistrer uniquement les caracteres visibles.
    Peut etre n'utilise pas l'objet Color mais travaille avec des nombres (codage RGB).
    Et utilise le vectorielle. C'est a dire que si tu fais une ligne tu enregistre uniquement x1,y1,x2,y2 et non pas tout les points de la ligne.

  3. #3
    Membre averti Avatar de mathieumadrid
    Étudiant
    Inscrit en
    Juin 2005
    Messages
    39
    Détails du profil
    Informations personnelles :
    Âge : 39

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2005
    Messages : 39
    Par défaut
    Pour les couleurs, je vais donc travailler avec un entier du type :
    rgb = r + g * 256 + b * 256 ^ 2
    avec
    r = rgb % 256
    g = (rgb / 256) % 256
    b = (rgb / 256 ^ 2) % 256

    A moins que tu pensais à un objet Couleur par exemple avec trois entiers r, g et b ? Mais ceci revient à étendre Color je pense...
    Sinon, pour les lignes, je suis obligé d'enregistrer tous les points.
    Merci pour ton aide.
    Si d'autre personnes ont des propositions d'optimisation alors elles sont les bienvenues.

  4. #4
    Membre émérite
    Profil pro
    Inscrit en
    Février 2007
    Messages
    572
    Détails du profil
    Informations personnelles :
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations forums :
    Inscription : Février 2007
    Messages : 572
    Par défaut
    Une image, c'est beaucoup de pixels. Par exemple :
    - une imagette : 100x100 => 10000
    - un image plein ecran : 1280x1024 => 1310720
    - un image d'un appareil photo : 2560x2048 => 5242880
    Si tu mets un objet par pixel, ca fait beaucoup d'objets au final, et donc:
    - il faut du temps pour creer tous ces objets
    - il faut de la memoire (il faut au moins doubler par rapport à une conception ou un pixel est represente par un int).
    Pour le trace, c'est pareil. Si le trace d'un pixel prend 1ms, pour une image de 10000 pixels, ca fait déjà 10s.

    Pour optimiser, il vaudrait mieux utiliser des objets de type BufferedImage, ou peut être
    MemoryImageSource.

    Enfin, ce que tu as ecrit est par super optimum
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    rgb = r + g * 256 + b * 256 ^ 2
    r = rgb % 256
    g = (rgb / 256) % 256
    b = (rgb / 256 ^ 2) % 256
    Ecris plutot
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    rgb = r | (g << 8)  | (256 <<16);
    r = rgb & 0xFF;
    g = (rgb >> 8) & 0xFF;
    b = (rgb >> 16) & 0xFF;
    Les decalages de bit, c'est plus rapide que les divisions, les modulos et les puissances.

  5. #5
    Membre averti Avatar de mathieumadrid
    Étudiant
    Inscrit en
    Juin 2005
    Messages
    39
    Détails du profil
    Informations personnelles :
    Âge : 39

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2005
    Messages : 39
    Par défaut
    Je dois les mettre où les BufferedImage ? Je dois remplacer mon cadre par ce type d'objet par exemple ? En lisant un peu la javadoc, je vois que l'on peut récupérer le graphics de l'image ! Cela veut dire que je peux dessiner dans le graphics de l'image buffer avec les méthodes prédéfinies de la classe Graphics ? Car dans mon application, j'utilise un cadre dans lequel je dessine mes propres figures (trait, rectangle, ellipse...). J'étais obligé d'écrire ces méthodes pour que l'image qui apparaît à l'écran soit permanente (car en dessinant dans le graphics du JPanel, l'image n'était pas permanente lorsque l'on déplaçait la JFrame en dehors de l'écran). Peut-on utiliser une BufferedImage pour remplacer mon cadre ? Si oui, comment ferais-tu pour assurer le rafraîchissement de l'image avec le modèle MVC ?
    Sinon, pour la formule avec décalages de bits, ça serait pas plutôt :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    rgb = r | (g << 8) | (b << 16);
    r = rgb & 0xFF;
    g = (rgb >> 8) & 0xFF;
    b = (rgb >> 16) & 0xFF;
    J'attends tes réponses avec impatience.

  6. #6
    Membre émérite
    Profil pro
    Inscrit en
    Février 2007
    Messages
    572
    Détails du profil
    Informations personnelles :
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations forums :
    Inscription : Février 2007
    Messages : 572
    Par défaut
    C'est le dessin que tu affichais s'effacait, c'est que tu as loupé un truc.

    Je te conseille de lire
    ce point (et le suivant) de la faq
    http://java.developpez.com/faq/gui/?...QUE_DESSIN_g2d
    ce post
    http://www.developpez.net/forums/sho...d.php?t=350628
    et ce cours
    http://www-igm.univ-mlv.fr/~berstel/...a/8-Dessin.pdf

    Je pense que ca t'aidera beaucoup.

    Pour le bout de code, effectivement c'est b et pas 256.

  7. #7
    Membre éclairé
    Profil pro
    Étudiant
    Inscrit en
    Juillet 2006
    Messages
    62
    Détails du profil
    Informations personnelles :
    Localisation : France, Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juillet 2006
    Messages : 62
    Par défaut
    Dans la méthode paint utilise la méthode drawImage pour dessiner ton buffered image.
    Ensuite si tu travaille en mvc, tu peut choisir d'effectuer les traitements des images dans le modèle. Une foi ces traitements effectuer le modèle notifie la vue. La vue va chercher les informations dans le modèle (ici en l'occurence ta vue peut contenir une instance de bufferedImage qu'elle remplacera à chaque notification par une instance contenue dans le modèle). Une foie l'image chargée utilise la méthode repaint pour repeindre ton component.
    Tu peut utiliser le component de ton choix.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. methode paint en java
    Par saheliano dans le forum 2D
    Réponses: 7
    Dernier message: 10/05/2010, 09h06
  2. Méthode paint Java
    Par dawaman dans le forum 2D
    Réponses: 1
    Dernier message: 02/04/2010, 11h55
  3. Chaine d'appel de paint(), java.awt
    Par Cbonniot dans le forum AWT/Swing
    Réponses: 9
    Dernier message: 22/12/2009, 11h12
  4. paint java 5 et java 6
    Par atha2 dans le forum AWT/Swing
    Réponses: 5
    Dernier message: 07/11/2007, 14h42
  5. [graphics] Paint en java
    Par soad dans le forum 2D
    Réponses: 2
    Dernier message: 14/04/2006, 14h47

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo