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

 Java Discussion :

Probleme Qualité d'affichage d'image dans JPanel


Sujet :

Java

  1. #1
    Membre éclairé Avatar de snay13
    Homme Profil pro
    Inscrit en
    Juin 2009
    Messages
    236
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Juin 2009
    Messages : 236
    Par défaut Probleme Qualité d'affichage d'image dans JPanel
    Bonjour je rencontre des difficultés pour avoir un affichage de qualité de mes images png dans un jpanel

    Je dois les ajuster à mon JPanel sans les déformer et je dispose d'image de formats differents (portait, paysage)

    Pouvez vous m'aider à améliorer la rapidité ainsi que la qualité d'affichage?

    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
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
     
    public class AfficheurImage extends JPanel
    {
        protected BufferedImage image = null, image2 = null, image3 = null;
        private int width, height;
        private double imageHeight, imageHeightPosition, imageWidthPostion;
     
        public AfficheurImage (int width, int height)
        {
            this.width = width; this.height = height;
            setBackground(Color.white);
        }
        public void setImage(String imagePath)
        {   
            try
            {
              File a = new File(imagePath);
                image = ImageIO.read(a);
                image = createCompatibleImage(image);
                image2 = ImageIO.read(a);
                image2 = createCompatibleImage(image2);
                double i;
                for (i = 0.45 ; image.getWidth() > width  ; i -= 0.01)
                {
                    System.out.println(i);
                    image = scale(image2, i);
                }
                image3 = scale(image2, i);
     
                imageHeight = image3.getHeight() * (width / image3.getWidth());
                imageHeightPosition = (height - imageHeight) / 2;
                imageWidthPostion = (width - image3.getWidth()) / 2;
            }
            catch (IOException ex) {  Logger.getLogger(AfficheurImage.class.getName()).log(Level.SEVERE, null, ex);   }
        }
        @Override
        protected void paintComponent(Graphics g)
        {
            super.paintComponent(g);
            g.drawImage(image3, (int) imageWidthPostion, (int) imageHeightPosition, null);
        }
        public void stopImage()
        {
            image3 = null;
        }
        /** Effectue une homothétie de l'image.
        *
        * @param bi l'image.
        * @param scaleValue la valeur de l'homothétie.
        * @return une image réduite ou agrandie.
        */
        public static BufferedImage scale(BufferedImage bi, double scaleValue)
        {
            AffineTransform tx = new AffineTransform();
            tx.scale(scaleValue, scaleValue);
            AffineTransformOp op = new AffineTransformOp(tx, AffineTransformOp.TYPE_BILINEAR);
            BufferedImage biNew = new BufferedImage( (int) (bi.getWidth() * scaleValue),
                    (int) (bi.getHeight() * scaleValue), bi.getType());
            return op.filter(bi, biNew);
        }
        /**
        * Create a compatible image from an existing image.
        *
        * @param image The image to make compatible.
        * @return A compatible image filled with the base image.
        */
        public static BufferedImage createCompatibleImage(BufferedImage image)
        {
            GraphicsConfiguration gc = GraphicsEnvironment.
                    getLocalGraphicsEnvironment().getDefaultScreenDevice().getDefaultConfiguration();
     
            if (image.getColorModel().equals(gc.getColorModel()))
            {
                return image;
            }
            else
            {
                BufferedImage compatibleImage = gc.createCompatibleImage(image.getWidth(), image.getHeight(),
                        image.getTransparency());
     
                Graphics g = compatibleImage.getGraphics();
                g.drawImage(image, 0, 0, null);
                g.dispose();
     
                return compatibleImage;
            }
        }
    }
    Merci

  2. #2
    Membre Expert
    Avatar de slim_java
    Homme Profil pro
    Enseignant
    Inscrit en
    Septembre 2008
    Messages
    2 272
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : Tunisie

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Septembre 2008
    Messages : 2 272
    Par défaut
    Salut,
    tu trouve ici la réponse des experts à ce problème.


  3. #3
    Expert confirmé
    Avatar de sinok
    Profil pro
    Inscrit en
    Août 2004
    Messages
    8 765
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Août 2004
    Messages : 8 765
    Par défaut
    Le problème de base étant bien sur que l'image a une définition par défaut, et qu'en l'agrandissant, il est obligatoire d'avoir une perte de qualité. La compression jpeg étant destructrice, elle fait d'autant plus mal. Une image en png (compression sans perte) résistant un peu mieux (mais ça reste limité)

  4. #4
    Membre éclairé Avatar de snay13
    Homme Profil pro
    Inscrit en
    Juin 2009
    Messages
    236
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Juin 2009
    Messages : 236
    Par défaut
    Merci pour vos reponses

    Apparemment mes images PNG sont plus grandes et c'est donc une réduction que je réalise. Si j'affiche mon image par le viewer de Windows à la même taille que je l'affiche dans mon application, la différence de qualité est flagrante avec des lignes qui ne se dessinent pas et des trous blancs

    J'ai regardé le lien que tu m'as donné slim_java mais j'utilise les mêmes techniques : des images compatibles et j'ai testé la fonction scale mais sans amélioration

    Faut il que je déplace mon post vers cette catégeorie de forum?

  5. #5
    Membre Expert
    Avatar de slim_java
    Homme Profil pro
    Enseignant
    Inscrit en
    Septembre 2008
    Messages
    2 272
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : Tunisie

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Septembre 2008
    Messages : 2 272
    Par défaut
    Bonjour,

    Citation Envoyé par snay13 Voir le message

    Faut il que je déplace mon post vers cette catégeorie de forum?
    non c'est pas la peine.

    Sinon, qu'est ce que ca donne si tu impose une taille à l'image au moment du dessin avec cette version de drawImage :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    g.drawImage(buffred_image, pos_X, pos_Y, largeur, hauteur, spectateur));

  6. #6
    Membre éclairé Avatar de snay13
    Homme Profil pro
    Inscrit en
    Juin 2009
    Messages
    236
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Juin 2009
    Messages : 236
    Par défaut
    Merci de me répondre

    J'ai essayé de diviser la largeur et la hauteur par 3 en shuntant la méthode scale tout en gardant des images compatibles mais le résultat est pire.

    Par contre je n'est pas compris le dernier paramètre de drawImage : spectateur

  7. #7
    Membre éclairé Avatar de snay13
    Homme Profil pro
    Inscrit en
    Juin 2009
    Messages
    236
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Juin 2009
    Messages : 236
    Par défaut
    Pour information je génère moi même ces images png à partir d'un fichier pdf gràce à ghostscript. Ces images s'affichent correctement dans le viewer de windows.

    Je crée ces images avec une résolution de 200

  8. #8
    Membre Expert
    Avatar de slim_java
    Homme Profil pro
    Enseignant
    Inscrit en
    Septembre 2008
    Messages
    2 272
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : Tunisie

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Septembre 2008
    Messages : 2 272
    Par défaut
    Citation Envoyé par snay13 Voir le message

    Par contre je n'est pas compris le dernier paramètre de drawImage : spectateur
    Puisqueton image est entièrement récupérée avant d'être affichée, le traitement est synchrone et de ce fait, il suffit de mettre ce paramètre à null

  9. #9
    Membre éclairé Avatar de snay13
    Homme Profil pro
    Inscrit en
    Juin 2009
    Messages
    236
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Juin 2009
    Messages : 236
    Par défaut
    Ok c'est ce que j'ai fait mais sans aucune amlioration

  10. #10
    Expert confirmé
    Avatar de sinok
    Profil pro
    Inscrit en
    Août 2004
    Messages
    8 765
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Août 2004
    Messages : 8 765
    Par défaut
    Essaie de redimensionner ton image en utilisant la méthode préconisée par Gfx: http://www.developpez.net/forums/d70...ion-miniature/

  11. #11
    Expert éminent
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Billets dans le blog
    1
    Par défaut
    Salut,

    Citation Envoyé par snay13 Voir le message
    Par contre je n'est pas compris le dernier paramètre de drawImage : spectateur
    Le dernier paramètre sert à signaler des changements dans l'image, et cela sert généralement à mettre à jour l'affichage.

    En général il suffit de passer la référence au composant courant (this), qui se chargera alors de faire un repaint() pour mettre à jour l'affichage.


    C'est utile dans deux cas :
    • Afin de ne pas bloquer l'affichage, certaines images sont chargées en arrière plan (c'est le cas avec Toolkit.getImage() et ImageIcon par exemple).
      Donc elles ne sont pas forcément entièrement chargées lorsqu'on veut les afficher, et l'ImageObserver permet d'être averti de cela afin d'afficher l'image dès qu'elle est chargée...
    • Dans le cas d'une image animé (GIF), cela permet d'afficher la nouvelle image


    a++

  12. #12
    Membre éclairé Avatar de snay13
    Homme Profil pro
    Inscrit en
    Juin 2009
    Messages
    236
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Juin 2009
    Messages : 236
    Par défaut


    Quelle difference !!!

    Le lien vers le post de gfx m'a résolu le problème. Je n'est plus de différence entre mon viewer Windows et mon affichage dans mon JPanel

    La qualité c'est pas tout et j'ai gagné en rapidité sur mon affichage

    Je poste la classe corrigé. Si vous avez des améliorations à proposer je suis preneur. Je le mets ce soir en résolu

    Merci à tous ceux qui ont participé à ce post

    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
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
     
    public class AfficheurImage extends JPanel
    {
        private BufferedImage image = null;
        private int width, height;
        private double imageHeightPosition, imageWidthPostion;
     
        public AfficheurImage (int width, int height)
        {
            this.width = width; this.height = height;
            setBackground(Color.white);
        }
        public void setImage(String imagePath)
        {   
            try
            {
                image = ImageIO.read(new File(imagePath));
                image = createCompatibleImage(image);
                image = createThumbnail(image, width);
     
                //Centrage de l'image
                double imageHeight = image.getHeight() * (width / image.getWidth());
                imageHeightPosition = (height - imageHeight) / 2;
                imageWidthPostion = (width - image.getWidth()) / 2;
     
            }
            catch (IOException ex)
            {
                Logger.getLogger(AfficheurImage.class.getName()).log(Level.SEVERE, null, ex);
            }
     
        }
        @Override
        protected void paintComponent(Graphics g)
        {
            super.paintComponent(g);
            g.drawImage(image, (int) imageWidthPostion, (int) imageHeightPosition, null);
        }
        public void stopImage()
        {
            image = null;
        }
        /**
        * Create a compatible image from an existing image.
        *
        * @param image The image to make compatible.
        * @return A compatible image filled with the base image.
        */
        public static BufferedImage createCompatibleImage(BufferedImage image)
        {
            GraphicsConfiguration gc = GraphicsEnvironment.
                    getLocalGraphicsEnvironment().getDefaultScreenDevice().getDefaultConfiguration();
     
            if (image.getColorModel().equals(gc.getColorModel()))
            {
                return image;
            }
            else
            {
                BufferedImage compatibleImage = gc.createCompatibleImage(image.getWidth(), image.getHeight(),
                        image.getTransparency());
     
                Graphics g = compatibleImage.getGraphics();
                g.drawImage(image, 0, 0, null);
                g.dispose();
     
                return compatibleImage;
            }
        }
        /**
         * Reduction de l'image
         * @param image
         * @param requestedThumbSize
         * @return
         */
        public static BufferedImage createThumbnail(BufferedImage image, int requestedThumbSize)
        {
            float ratio = (float) image.getWidth() / (float) image.getHeight();
            int width = image.getWidth();
            BufferedImage thumb = image;
     
            do
            {
                width /= 2;
                if (width < requestedThumbSize)
                {
                    width = requestedThumbSize;
                }
     
                BufferedImage temp = new BufferedImage(width, (int) (width / ratio), BufferedImage.TYPE_INT_ARGB);
                Graphics2D g2 = temp.createGraphics();
                g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
                g2.drawImage(thumb, 0, 0, temp.getWidth(), temp.getHeight(), null);
                g2.dispose();
     
                thumb = temp;
            } while (width != requestedThumbSize);
     
            return thumb;
        }
    }

  13. #13
    Expert confirmé
    Avatar de sinok
    Profil pro
    Inscrit en
    Août 2004
    Messages
    8 765
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Août 2004
    Messages : 8 765
    Par défaut
    L'amélioration la plus évidente serait de faire la lecture et la miniaturisation de l'image dans un SwingWorker afin d'éviter le bloquage de l'EDT par ces opérations un tant soit peu lourdes niveau ressources.

  14. #14
    Expert confirmé
    Avatar de sinok
    Profil pro
    Inscrit en
    Août 2004
    Messages
    8 765
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Août 2004
    Messages : 8 765
    Par défaut
    A noter que les deux méthodes que tu as intégrées dans ton code (le redimensionnement et la gestion des images compatibles) dont toutes deux tirées de la classe GraphicsUtilities mise à disposition par Gfx (classe qui fait partie désormais du projet SwingX)

  15. #15
    Membre éclairé Avatar de snay13
    Homme Profil pro
    Inscrit en
    Juin 2009
    Messages
    236
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Juin 2009
    Messages : 236
    Par défaut
    J'avoue ne connaitre le projet swingx que de nom mais je vais regarder cela de plus près

    pour les swingworker je les integre déjà dans mon appli c'était une classe test

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

Discussions similaires

  1. [A-03] Probleme d'affichage d images dans un etat
    Par zeero_cool dans le forum IHM
    Réponses: 3
    Dernier message: 22/10/2008, 12h57
  2. probleme avec l'affichage des images dans une jsp
    Par hypothese dans le forum Servlets/JSP
    Réponses: 12
    Dernier message: 27/05/2008, 17h56
  3. Affichage d'image dans un Jpanel
    Par vince351 dans le forum AWT/Swing
    Réponses: 13
    Dernier message: 22/03/2007, 12h27
  4. Probleme d'affichage d'image dans une fenetre
    Par cgregueusse dans le forum MFC
    Réponses: 1
    Dernier message: 03/08/2005, 12h08

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