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

AWT/Swing Java Discussion :

[swing][Buffered Image] memoire et lenteur sont les deux ...


Sujet :

AWT/Swing Java

  1. #1
    Membre habitué
    Homme Profil pro
    Chef de projet NTIC
    Inscrit en
    Juin 2005
    Messages
    175
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Chef de projet NTIC

    Informations forums :
    Inscription : Juin 2005
    Messages : 175
    Points : 145
    Points
    145
    Par défaut [swing][Buffered Image] memoire et lenteur sont les deux ...
    Petit hors sujet d'emblée : Bon alors la je ne comprend plus. je vais vous soumettre un probleme qui aura été le fil rouge de mon projet de stage et vraiment j'en suis pas loin de casser l'écran ce qui serait dommage vu que c'est un portable..

    pour afficher des moultitudes de comoposants sur un panel de display, je recupere leurs images dans une base de donnée et ej crée une buffered image grace a plusieurs methodes. Puis a chaque paint du panel, je repaint les images des components.

    Le probleme si je met les images en BufferedImage.TYPE_INT_RGB, c'est que la mémoire sature très (très très) vite. pour y rémdier j'ai utilisé le type BufferedImage.TYPE_BYTE_INDEXED , qui code sur 256 couleurs, alors oui les composants sont moins beaux mais qu'est ce que je gagne comme mémoire. Pour avoir un MemoryExeption , il faut vraiment etre mechant avec le programme.

    Mais voila, autant a l'ecran ca passe, autant une fois imprimé certains composants (des représentations de trains en fait), sont blindés de glitches genants. (ce n'est pas "trop" grave pour les autres composants)

    Donc comme ce sont des composants d'arriere plan et de toute manière en noir blanc et gris, je me dit : facile j'utilise TYPE_BYTE_BINARY pour les composants de type "train" et en effet ca marche. a l'impression les trains sont tous blancs a l'interieur plus de glitches, ca fait kan meme plus "pro".

    Mais voila le mais : les projest qui contiennent ces composants dont l'image est recalculée en binary deviennent impossibles à éditer, tout rame a mort c'est une catastrophe. ale probleme ne sempble meme pas venir de la conversion en binary qui est effectivement longue, mais le composant sempble avoir acquis une "lourdeur" immense !

    la vraiment, j'ai rarement autant séché. donc merci a ceux qui peuvent m'aider.

  2. #2
    Gfx
    Gfx est déconnecté
    Expert éminent
    Avatar de Gfx
    Inscrit en
    Mai 2005
    Messages
    1 770
    Détails du profil
    Informations personnelles :
    Âge : 41

    Informations forums :
    Inscription : Mai 2005
    Messages : 1 770
    Points : 8 178
    Points
    8 178
    Par défaut
    Quand récupères-tu les images ? Combien d'images as-tu ? Si tu as une MemoryException j'imagine que tu as BEAUCOUP d'images ou que tu as une fuite mémoire dans ton code. J'ai utilisé des centaines de BufferedImage.TYPE_INT_ARGB à la fois (chacune de 300x300 pixels environ) et je n'avais pas de souci de mémoire.

    Pour ton problème de lenteur ça doit venir de ta conversion. Il manque pas mal d'infos là : comment le fais-tu, à quelle fréquence, etc.
    Romain Guy
    Android - Mon livre - Mon blog

  3. #3
    Membre habitué
    Homme Profil pro
    Chef de projet NTIC
    Inscrit en
    Juin 2005
    Messages
    175
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Chef de projet NTIC

    Informations forums :
    Inscription : Juin 2005
    Messages : 175
    Points : 145
    Points
    145
    Par défaut
    oui tu as raison, mais mon post etant deja peu clair je n'ai pas voulu trop vous assomer. Si j'ai une fuite memoire et que tu me dis ou, je t'envoie une carte postale !

    Attention je balance tout, donc ca rique de pas etre simple a avaler.

    voici la methode qui recupere l'image en bdd :



    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
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    /**
         * method used for retrieving an image by knowing its part ID.<br>
         * It converts the Blob stored in DB in a java object "Image".
         * @param forPartInterface if true, it means that the component will be used 
         * as generic in generic parts interface (pakage "component"). else, it may be a 
         * project part, or a generic part designed to be added in a project.
         * @param id the id of the part from which we want to find an image.
         * @param isGeneric wheter or not the component is generic (really generic, not 
         * depending of what usage will be made of this component).<br>
         * It is used to know in which table we must search the component.
         * @return : a java "Image"
         */
        public static Image retrieveImageFromPartByID(Integer id, boolean isGeneric,
                boolean forPartInterface) {
            if (id == null) {
                System.out.println("DbManager: can not retrieve" +
                        " an image with part's ID null");
                return null;
            }
            try {                                 
                String query;
                int typeImage = UtilityManager.TYPE_BUFFERED_IMAGES; 
                // see UtilityManager.TYPE_BUFFERED_IMAGES declaration.
                if (isGeneric)  {
                    query = "SELECT image,id_type FROM generic_part " +
                            "WHERE id_generic_part = ?"; 
     
                    // must not degrade a generic image because
                    // it can be resaved in db :
                    typeImage = BufferedImage.TYPE_INT_RGB; 
     
                }
                else {
                    query = "SELECT gp.image,gp.id_type FROM generic_part AS gp," +
                            " project_part AS pp" +
                            " WHERE pp.id_project_part = ?" +
                            " AND pp.id_generic_part = gp.id_generic_part";                    
                }
                PreparedStatement stmt = connection.prepareStatement(query);
                stmt.setInt(1, id.intValue());
     
                // copy the image from the DB to Blob.
                ResultSet rs = stmt.executeQuery();    
                if(rs.next()) {
                      // "1" because the blob is the first field retrieved by the query 
                      Blob blob = rs.getBlob(1); 
                      InputStream in = blob.getBinaryStream();
     
                      // if it is a train (and not a generic part), we change the type
                      // of the buffered image to black & white
                      Integer idType = new Integer(rs.getInt(2));                      
                      if (forPartInterface == false && idType.intValue() == 
                              getIdTypeByStringType("Train").intValue()) {
                          typeImage = BufferedImage.TYPE_BYTE_BINARY;
                          //typeImage = BufferedImage.TYPE_INT_ARGB_PRE;
                      }
     
                      // finally we can create this buffered image
                      BufferedImage im = ImageIO.read (
                              new FileCacheImageInputStream (
                                      new BufferedInputStream (in),
                                      new File(".")));
                      im = ImgTools.toBufferedImage(im, typeImage);                                    
     
                      rs.close();
                      stmt.close();
                      System.out.println("image retrieved in table " +
                            "'generic_component'");
                      return im;
                }
              }
              catch (Exception ex){
                  ex.printStackTrace();                  
              } 
              System.out.println("DbManager: Warning, image with part's ID :" + id + 
              "can not be loaded");
              return null;        
        }
    la methode paint du composant :

    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
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    /**
         * Paints the component in the specified graphic context
         * (draws the image, at the position and with the size definined 
         * in this component properties)
         * @param g the graphic context in which the part has to be paint
         */
        public void paint(Graphics g) {
            if (getImage() != null) { // a security, but a Part is supposed to own an image!
     
     
                // the image drawing itself
                // if it is not a wire, we display the image, else we paint the wire
                // by using the specific method
                if (wire == null) {
                    g.drawImage(getImageToPaint(),
                            (int) (getPosWidth().intValue() * UtilityManager.zoomvalue), 
                            (int) (getPosHeight().intValue() * UtilityManager.zoomvalue),
                            (int) (getDefaultWidth().intValue() * UtilityManager.zoomvalue),
                            (int) (getDefaultHeight().intValue() * UtilityManager.zoomvalue),
                            this);
                } else {
                    wire.paintWire(this, g);
                }
     
     
                // if "selected" and not "drag Mode", we add a rectangle
                // around the image
                if (isSelected() && paintSpecialDrag == false) {
                    //g.setColor(Color.RED);
                    g.setColor(Color.BLUE);
                    g.draw3DRect(
                            (int) (getPosWidth().intValue() * UtilityManager.zoomvalue),
                            (int) (getPosHeight().intValue() * UtilityManager.zoomvalue),
                            (int) (getDefaultWidth().intValue() 
                                    * UtilityManager.zoomvalue),
                            (int) (getDefaultHeight().intValue() 
                                    * UtilityManager.zoomvalue),
                            true);
                    g.setColor(Color.BLACK);
                }           
            }
            paintSpecialDrag = false; // the next paint will be a normal one 
            // (except if called by a drag, of course)
     
            // we put a tool tip with some informations
            // especially useful for debug :
            setToolTipText(getName() + " posX:" + getPosWidth() + " posY:" +
                    getPosHeight() + " sizeX:" + getDefaultWidth() + " sizeY:" +
                    getDefaultHeight());
        }
    la methode paint du panel qui contient les composants :

    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
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    public void paint(Graphics g) {
            //      removing what has previously been displayed
            g.setColor(Color.WHITE);
            g.fillRect(0, 0, getWidth(), getHeight());
     
     
            //		we display all the components of the projectPartSet 
            //      in the PanelProjectDisplay
            //		we add in the REVERSE order for a "selection of components"
            //      question. do not change this.
            Vector theVector = getFrameMainProjetDesign().getProject().
                getProjectPartVector();    
            removeAll();
            for (int i = 0; i < theVector.size(); i++) {
                ProjectPart pToPaint = (ProjectPart)(theVector.get(i));
                ProjectPart pToAdd = (ProjectPart)(theVector.get(theVector.size()-1-i));
     
              // we repaint the component :              
              pToPaint.update(g); // We paint this Part, in the same graphical context
     
              // we add the other component
              add(pToAdd);
              pToAdd.setBounds(
                      (int) (pToAdd.getPosWidth().intValue() * UtilityManager.zoomvalue),
                      (int) (pToAdd.getPosHeight().intValue() * UtilityManager.zoomvalue),
                      (int) (pToAdd.getDefaultWidth().intValue() *
                              UtilityManager.zoomvalue),
                      (int) (pToAdd.getDefaultHeight().intValue() *
                              UtilityManager.zoomvalue));          
            }
            // we update the title Bar
            getFrameMainProjetDesign().updateTitleBar();
     
            // we display the selection-rectangle if needed
            if (draggedPoint.equals(pressedPoint) == false) {            
                g.setColor(Color.GRAY);
                g.drawRect(
                        Math.min(pressedPoint.x, draggedPoint.x),
                        Math.min(pressedPoint.y, draggedPoint.y),
                        Math.abs(pressedPoint.x - draggedPoint.x),
                        Math.abs(pressedPoint.y - draggedPoint.y));
            }
     
        }
    la methode qui met le composant dans le bon sens (il y a 4 sens pour mes rectangles : 0, 90,180 et 270°)

    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
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    /**
         * this method performs a rotation on the imageToPaint. it depends on the 
         * rotationMode. It must not be called as is, but in a "rotate" context
         * <br>(because the image is not the only thing to modify in case of a
         * rotation on the part)
         */
        private void setImageToPaintOrientation() {
            int max = Math.max(getImage().getWidth(null), getImage().getHeight(null));
            int typeImage = UtilityManager.TYPE_BUFFERED_IMAGES;
            if (this.getType().equals("Train")) {
                typeImage = BufferedImage.TYPE_BYTE_BINARY;
            }
     
            imageToPaint = ImgTools.toBufferedImage(
                    getImage().getScaledInstance(max, max, Image.SCALE_FAST),
                        typeImage);
    //        int colorBufferedRotated = UtilityManager.TYPE_BUFFERED_IMAGES;
    //        // if it is a train (black & white image), we must avoid graphical glitches.
    //        if (this.getType().equals("Train")) {
    //            //colorBufferedRotated = BufferedImage.TYPE_INT_ARGB;
    //            colorBufferedRotated = BufferedImage.TYPE_BYTE_BINARY;
    //        }
    //        int colorBufferedRotated = typeImage; // TODO débile a virer
            // we set the  imageToPaint depending of the Part orientation
            switch (rotationMode) {
    	    	case ROTATION_90 :
    	    	    imageToPaint = ImgTools.rotate(imageToPaint, 90,
                            typeImage);
    	    	    break;
    	    	case ROTATION_180 :
    	    	    imageToPaint = ImgTools.rotate(imageToPaint, 180,
                            typeImage);    	    
    	    	    break;
    	    	case ROTATION_270 :
    	    	    imageToPaint = ImgTools.rotate(imageToPaint, 270,
                            typeImage);
    	    	    break;
    		    default: // normal mode : no rotation needed.
                    break;	        
            }
        }
    et enfin la methode de toBufferedImage :

    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
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    /**
     * convertissor of an image to a buffered image : 
     * (function picked at <a href="http://www.developpez.com" target="_blank">www.developpez.com</a> and modified by P. Cellard in july 2005)
     * @param image : the image to be converted in a BufferedImage
     * @param typeImage the type of Buffered image (should be : BufferedImage.TYPE_INT_RGB
     *  or BufferedImage.TYPE_BYTE_INDEXED or BufferedImage.TYPE_BYTE_GRAY
     * @return the BufferedImage generated
     */
    public static BufferedImage toBufferedImage(Image image, int typeImage) {
                  /* we verify that image is fully loaded */
                  image = new ImageIcon(image).getImage();
     
                  /* Creation of the new image */
                  BufferedImage bufferedImage = new BufferedImage(
                                                        image.getWidth(null),
                                                        image.getHeight(null),
                                                        typeImage);
     
                  // type Image should be : BufferedImage.TYPE_INT_RGB or 
                  // BufferedImage.TYPE_BYTE_INDEXED);                                                    
                  Graphics g = bufferedImage.createGraphics();
                  g.drawImage(image, 0, 0, null);
     
                  /* freeing memory */
                  g.dispose();
                  image.flush();
                  image = null; 
                  return bufferedImage;
      }
    bon ben si tu t'en dépetre, toi ou un autre, vraiment je serais tres agreablement surpris. mais bon la au moins t'a le code

  4. #4
    Gfx
    Gfx est déconnecté
    Expert éminent
    Avatar de Gfx
    Inscrit en
    Mai 2005
    Messages
    1 770
    Détails du profil
    Informations personnelles :
    Âge : 41

    Informations forums :
    Inscription : Mai 2005
    Messages : 1 770
    Points : 8 178
    Points
    8 178
    Par défaut
    J'y jette un oeil demain, là... dodo
    Romain Guy
    Android - Mon livre - Mon blog

  5. #5
    Membre habitué
    Homme Profil pro
    Chef de projet NTIC
    Inscrit en
    Juin 2005
    Messages
    175
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Chef de projet NTIC

    Informations forums :
    Inscription : Juin 2005
    Messages : 175
    Points : 145
    Points
    145
    Par défaut
    ca c'est sympa :d

  6. #6
    Membre du Club Avatar de lebesnec
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    82
    Détails du profil
    Informations personnelles :
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Mai 2005
    Messages : 82
    Points : 63
    Points
    63
    Par défaut
    juste au cas ou ... vérifie que la méthode paint n'est pas appelé en boucle en mettant un system.out.println(...) dedans, j'ai dèja eu pas mal de problème avec ça
    Chercher dans la Javadoc directement depuis Firefox / IE7 : http://lebesnec.free.fr/?p=8

  7. #7
    Membre expert Avatar de KiLVaiDeN
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    2 851
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2003
    Messages : 2 851
    Points : 3 481
    Points
    3 481
    Par défaut
    Peut-être gagnerais-tu à utiliser un profiler sur ton programme pour voir où se trouve ta grosse consommation de mémoire.

    Par contre je ne suis pas suffisament bon en GUI pour t'aider pour ton code, mais vite fait, je pense que tu déclares des variables au niveau local ( dans tes méthodes statiques ) et peut-être gagnerais-tu à les déclarer elles aussi en static, afin que le bloc mémoire soit réservé une fois pour toutes.
    K

  8. #8
    Membre habitué
    Homme Profil pro
    Chef de projet NTIC
    Inscrit en
    Juin 2005
    Messages
    175
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Chef de projet NTIC

    Informations forums :
    Inscription : Juin 2005
    Messages : 175
    Points : 145
    Points
    145
    Par défaut
    Citation Envoyé par KiLVaiDeN
    Peut-être gagnerais-tu à utiliser un profiler sur ton programme pour voir où se trouve ta grosse consommation de mémoire.

    Par contre je ne suis pas suffisament bon en GUI pour t'aider pour ton code, mais vite fait, je pense que tu déclares des variables au niveau local ( dans tes méthodes statiques ) et peut-être gagnerais-tu à les déclarer elles aussi en static, afin que le bloc mémoire soit réservé une fois pour toutes.
    ce sont des idées a creuser c'est certain. cela dit, avec mes images dégradées ca marche , je ne comprend pas pkoi c'est si lent avec des images binaires ...

  9. #9
    Membre expert Avatar de KiLVaiDeN
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    2 851
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2003
    Messages : 2 851
    Points : 3 481
    Points
    3 481
    Par défaut
    Au niveau de la mémoire, c'est un peu le même principe que pour les flux : plus les "tranches" à manipuler sont petites, plus c'est facile à gérer. Le GC a moins de mal à réclamer des petites ressources, et à les libérer, que dans le cas de grosses ressources ( car du coup il doit jouer plus souvent avec le cache )

    Ce n'est qu'une supposition
    K

  10. #10
    Membre habitué
    Homme Profil pro
    Chef de projet NTIC
    Inscrit en
    Juin 2005
    Messages
    175
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Chef de projet NTIC

    Informations forums :
    Inscription : Juin 2005
    Messages : 175
    Points : 145
    Points
    145
    Par défaut
    avec un profiler (au passage je recommande a tout le monde : YourKit Java Profiler 4.5, je suis pas pret de m'en séparer de celui la!), je demontre que :

    1) avec les images en noir et blanc : l'image de train prend tres peu en memoire (moins de 250k c'est sur), mais la methode sun.java2D.drawImage , appelée par Graphics.drawImage dans mon paint, prend presque tout le temps micropro.

    2) avec les images full color, la taille des images passe à 3,2 mega PAR IMAGE, mais leprog es plus rapide (edit : et la methode paint de ci dessus prend un temps ridicule , c'est un peu incroyable ):

    conclusions : il y a un probleme dans la methode sun.java2D.drawImage pour l'affichage d'image de type TYPE_BYTE_BINARY et les images en full color (et surement les autres) sont stockées en RAW dans la memoire et surtout pas en jpg bien que dans la bdd ce soit du jpg. Enfin cela je le savais deja.

    remedes ? :
    il y a deux possibilités :
    1) je trouve une autre methode plus rapide pour peindre les images que je veux en noir et blanc d'ou question pour vous ; une telle methode existe elle ?

    2) je trouve une methode pour que les images ne prennent pas 3.2 megas en memoire dans le cas du full color, et la j'y gagne en qualité. (bon faut pas non plus que l'affichage beacuoup plus long, sinon j'aurai encore tourn en rond)

    merci à ceux qui m'ont lu et a ceux (encore plus :p) qui me repondront.
    Pierre

  11. #11
    Gfx
    Gfx est déconnecté
    Expert éminent
    Avatar de Gfx
    Inscrit en
    Mai 2005
    Messages
    1 770
    Détails du profil
    Informations personnelles :
    Âge : 41

    Informations forums :
    Inscription : Mai 2005
    Messages : 1 770
    Points : 8 178
    Points
    8 178
    Par défaut
    Il est très difficile de profiler les opérations de dessin Java2D car certaines opérations peuvent, ou non, être déléguées à la carte graphique. Dans ton cas il semblerait que l'affichage des images en couleur soit réalisé entièrement par le matériel mais que pour une raison quelconque l'affichage en BINARY soit en software ou nécessite des opérations préalables.

    A voir ton code rapidement je dirais que tu devrais pouvoir mettre en cache le résultat du dessin. Le paint() de ton panneau ne dessinerait donc qu'une image à la fois, composée de toutes les autres images. C'est bien sûr valable si tu ne dois pas gérer des interactions complexes avec l'utilisateur (mouse over, etc.)

    Ensuite tu ne gères pas la zone de clipping. Je ne sais pas dans quelle mesure ça influe sur les performances de ton application mais c'est un point à considérer.

    Enfin je te conseille de contacter Chet Haase ou Chris Campbell chez Sun (les emails sont prénom.nom@sun.com), ils pourront te renseigner car ils bossent sur l'implémentation de ces trucs là
    Romain Guy
    Android - Mon livre - Mon blog

  12. #12
    Membre expert Avatar de KiLVaiDeN
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    2 851
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2003
    Messages : 2 851
    Points : 3 481
    Points
    3 481
    Par défaut
    Il me semble que les cartes graphiques peuvent gérer le ARGB en natif, eventuellement le BGRA, mais le ABGR pas forcément, peut-être que le problème vient de là ? Je ne sais pas d'où je sors ça ( impossible de trouver sur google ) mais je pense avoir entendu parler de ça quelque part..
    K

  13. #13
    Membre habitué
    Homme Profil pro
    Chef de projet NTIC
    Inscrit en
    Juin 2005
    Messages
    175
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Chef de projet NTIC

    Informations forums :
    Inscription : Juin 2005
    Messages : 175
    Points : 145
    Points
    145
    Par défaut
    tout d'abord merci de vos reponses.

    Citation Envoyé par Gfx
    Il est très difficile de profiler les opérations de dessin Java2D car certaines opérations peuvent, ou non, être déléguées à la carte graphique. Dans ton cas il semblerait que l'affichage des images en couleur soit réalisé entièrement par le matériel mais que pour une raison quelconque l'affichage en BINARY soit en software ou nécessite des opérations préalables.
    voila une explication qui me parait pleine de bon sens, tu as sans doute raison. mais ca ne va pas regler le probleme


    Citation Envoyé par Gfx
    A voir ton code rapidement je dirais que tu devrais pouvoir mettre en cache le résultat du dessin. Le paint() de ton panneau ne dessinerait donc qu'une image à la fois, composée de toutes les autres images. C'est bien sûr valable si tu ne dois pas gérer des interactions complexes avec l'utilisateur (mouse over, etc.)
    tu veux dire en utilisan une BufferedImage ? le probleme, c'est que je gere a peu pres tous les mouselisteners qui existent sur chaque composant.

    Citation Envoyé par Gfx
    Ensuite tu ne gères pas la zone de clipping. Je ne sais pas dans quelle mesure ça influe sur les performances de ton application mais c'est un point à considérer.
    c'est a dire ?( kézako zone de clipping?)

    Citation Envoyé par Gfx
    Enfin je te conseille de contacter Chet Haase ou Chris Campbell chez Sun (les emails sont prénom.nom@sun.com), ils pourront te renseigner car ils bossent sur l'implémentation de ces trucs là
    je leur envoie un mail, on verra bien si ils repondent.

    Citation Envoyé par KiLVaiDeN
    Il me semble que les cartes graphiques peuvent gérer le ARGB en natif, eventuellement le BGRA, mais le ABGR pas forcément, peut-être que le problème vient de là ? Je ne sais pas d'où je sors ça ( impossible de trouver sur google ) mais je pense avoir entendu parler de ça quelque part..
    c'est possible, mais rien ne prouve qu'il n'y a pas des differences entres les moultes cartes gqui existent. or il me faut une solution standard.

  14. #14
    Gfx
    Gfx est déconnecté
    Expert éminent
    Avatar de Gfx
    Inscrit en
    Mai 2005
    Messages
    1 770
    Détails du profil
    Informations personnelles :
    Âge : 41

    Informations forums :
    Inscription : Mai 2005
    Messages : 1 770
    Points : 8 178
    Points
    8 178
    Par défaut
    Chaque fois que tu reçois un Graphics, tu as aussi une zone de clipping que Swing (ou AWT d'ailleurs) te donne pour te dire quelle zone du composant doit être redessinée. Par exemple si tu as un composant de 500x500 pixels et que tu déplaces une fenêtre de 10x10 par dessus, Swing te dira de redessiner un Rectangle de 10x10 pixels à une certaine position.

    Ainsi dans la méthode paintComponent() au lieu de faire un g.fillRect(0, 0, getWidth(), getHeight()) il vaut mieux faire un g2.fill(g2.getClip()) (g2 étant un Graphics2D). Tu peux obtenir un Rectangle plutôt qu'une Shape en faisant g.getClipRect().

    Bref l'idée est de dessiner de manière à ne dessiner QUE ce qui se trouve dans le rectangle de clipping. Swing/Java2D fera quand même des optimisations si tu ne fais pas ça mais tu peux perdre énormément de temps à t'occuper de composants qui sont en fait en dehors de la zone de clipping. Il y a des méthodes dans Rectangle pour tester l'intersection avec un autre Rectangle.

    Note : évite de surcharger paint(), surcharge plutôt paintComponent().
    Romain Guy
    Android - Mon livre - Mon blog

  15. #15
    Membre habitué
    Homme Profil pro
    Chef de projet NTIC
    Inscrit en
    Juin 2005
    Messages
    175
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Chef de projet NTIC

    Informations forums :
    Inscription : Juin 2005
    Messages : 175
    Points : 145
    Points
    145
    Par défaut
    Chaque fois que tu reçois un Graphics, tu as aussi une zone de clipping que Swing (ou AWT d'ailleurs) te donne pour te dire quelle zone du composant doit être redessinée. Par exemple si tu as un composant de 500x500 pixels et que tu déplaces une fenêtre de 10x10 par dessus, Swing te dira de redessiner un Rectangle de 10x10 pixels à une certaine position.
    c'est malin !

    Ainsi dans la méthode paintComponent() au lieu de faire un g.fillRect(0, 0, getWidth(), getHeight()) il vaut mieux faire un g2.fill(g2.getClip()) (g2 étant un Graphics2D). Tu peux obtenir un Rectangle plutôt qu'une Shape en faisant g.getClipRect().

    Bref l'idée est de dessiner de manière à ne dessiner QUE ce qui se trouve dans le rectangle de clipping. Swing/Java2D fera quand même des optimisations si tu ne fais pas ça mais tu peux perdre énormément de temps à t'occuper de composants qui sont en fait en dehors de la zone de clipping. Il y a des méthodes dans Rectangle pour tester l'intersection avec un autre Rectangle.
    je vais essayer ca, mais je suis pas sur que ca reglera d'emblee le probleme.

    Note : évite de surcharger paint(), surcharge plutôt paintComponent().
    et pourquoi et pourquoi ? (c'est pas mon point fort java2D comme tu le vois)

  16. #16
    Gfx
    Gfx est déconnecté
    Expert éminent
    Avatar de Gfx
    Inscrit en
    Mai 2005
    Messages
    1 770
    Détails du profil
    Informations personnelles :
    Âge : 41

    Informations forums :
    Inscription : Mai 2005
    Messages : 1 770
    Points : 8 178
    Points
    8 178
    Par défaut
    Car paint() s'occupe de certaines choses pour toi. Ainsi si tu veux que ton composant gère une bordure, paint() appellera paintBorder() alors que ton paint() ne le fait pas. Bref, ça et d'autres choses.

    Pour le clipping, ça peut changer beaucoup de choses si tu as beaucoup de composants, et une zone d'affichage assez grande. Enfin, essaye et tu me diras. Note que parfois la gestion du clipping peut devenir assez complexe.
    Romain Guy
    Android - Mon livre - Mon blog

  17. #17
    Membre habitué
    Homme Profil pro
    Chef de projet NTIC
    Inscrit en
    Juin 2005
    Messages
    175
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Chef de projet NTIC

    Informations forums :
    Inscription : Juin 2005
    Messages : 175
    Points : 145
    Points
    145
    Par défaut
    Citation Envoyé par Gfx
    Car paint() s'occupe de certaines choses pour toi. Ainsi si tu veux que ton composant gère une bordure, paint() appellera paintBorder() alors que ton paint() ne le fait pas. Bref, ça et d'autres choses.

    Pour le clipping, ça peut changer beaucoup de choses si tu as beaucoup de composants, et une zone d'affichage assez grande. Enfin, essaye et tu me diras. Note que parfois la gestion du clipping peut devenir assez complexe.
    j'essaie tout ca, mais comme tu le dis pour le clipping ca peut s'avere tendu etant donné le fouillis de mon code d'affichage (et je ne parle pas des listeners)

Discussions similaires

  1. Réponses: 1
    Dernier message: 28/05/2014, 22h17
  2. Peut-on savoir si les images d'un site sont indexées?
    Par laurentinho dans le forum Référencement
    Réponses: 2
    Dernier message: 24/03/2009, 16h43
  3. Réponses: 5
    Dernier message: 11/09/2006, 17h29
  4. Réponses: 2
    Dernier message: 07/12/2005, 14h15

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