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

Composants Java Discussion :

[JLabel] Affichage et redimensionnement d'une image dans un JLabel


Sujet :

Composants Java

  1. #1
    Membre à l'essai
    Homme Profil pro
    Ingénieur process
    Inscrit en
    Mars 2017
    Messages
    17
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Ingénieur process
    Secteur : Industrie

    Informations forums :
    Inscription : Mars 2017
    Messages : 17
    Points : 17
    Points
    17
    Par défaut [JLabel] Affichage et redimensionnement d'une image dans un JLabel
    Bonjour,

    Je souhaite afficher une image dans un JLabel, lui-même contenu dans un JPanel.

    Pour ça, pas de problème, j'utilise le code suivant qui fonctionne très bien :
    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
     
    public class testImageLabel extends JFrame {
    	private JPanel panel = new JPanel();
    	private JLabel imageLabel;
    	private ImageIcon icon = new ImageIcon("Image.jpg");
     
    	public testImageLabel() {
    	    this.setLocationRelativeTo(null);
    	    this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                this.setTitle("Test Image Label");
    	    this.setSize(400, 300);
     
    	    imageLabel = new JLabel(icon);
    	    this.panel.add(imageLabel);
    	    this.panel.setBackground(Color.white);
    	    this.getContentPane().add(panel);
    	    this.setVisible(true);
    	}
     
    	public static void main(String[] args) {
    		testImageLabel test = new testImageLabel();
    	}
    }
    Le problème est que l'image est plus grande que le JLabel, elle est donc tronquée, il en manque une partie.

    J'ai cherché à réduire sa taille pour l'adapter à celle du JPanel, je me suis notamment inspiré de ce post https://www.developpez.net/forums/d8...-image-jlabel/.
    Voici mon code adapté :
    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
     
    public class testImageLabel extends JFrame {
    	private JPanel panel = new JPanel();
    	private JLabel imageLabel;
    	private ImageIcon icon = new ImageIcon("Image.jpg");
     
    	public testImageLabel() {
    	    this.setLocationRelativeTo(null);
    	    this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                this.setTitle("Test Image Label");
    	    this.setSize(400, 300);
     
    	    Image imageZoom = scaleImage(icon.getImage(), 100);
    	    Icon scaledIcon = new ImageIcon(imageZoom);
    	    imageLabel = new JLabel("Label", scaledIcon, 10);
    	    panel.add(imageLabel, BorderLayout.CENTER);
     
    	    this.panel.setBackground(Color.white);
    	    this.getContentPane().add(panel);
    	    this.setVisible(true);
    	}
     
    	//Méthode pour redimensionner une image
    	public static Image scaleImage(Image source, int width, int height) {
    	    BufferedImage img = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
    	    Graphics2D g = (Graphics2D)img.getGraphics();
    	    g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
    	    g.drawImage(img, 0, 0, width, height, null);
    	    g.dispose();
    	    return img;
    	}
     
    	//Méthode de calcul (en pixels) des paramètres widht et height de la méthode précédente
    	public static Image scaleImage(Image source, int size) {
    		int width = source.getWidth(null);
    		int height = source.getHeight(null);
    		double f = 0;
    		if (width < height) { // portrait
    		    f = (double)height / (double)width;
    		    width = (int)(size / f);
    		    height = size;
    		} else { //paysage
    		    f = (double)width / (double)height;
    		    width = size;
    		    height = (int)(size / f);
    		}
    		return scaleImage(source, width, height);
    	}
     
    	public static void main(String[] args) {
    		testImageLabel test = new testImageLabel();
    	}
    }
    Et là, le problème est que ça n'affiche pas l'image dans le JLabel, il y a uniquement le petit texte "Label" qui apparaît, laissant deviner que le JLabel est bien présent dans le JPanel. Je n'ai pas d'erreur de compilation.

    J'ai fait différents essais, mais sans succès. Je ne comprends pas où est le problème. Quelqu'un voit-il le problème ? ou comment afficher l'image ?

  2. #2
    Modérateur
    Avatar de joel.drigo
    Homme Profil pro
    Ingénieur R&D - Développeur Java
    Inscrit en
    Septembre 2009
    Messages
    12 430
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D - Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2009
    Messages : 12 430
    Points : 29 131
    Points
    29 131
    Billets dans le blog
    2
    Par défaut
    Salut

    1. L'erreur se situe dans la méthode Image scaleImage(Image source, int width, int height) là :

      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      g.drawImage(img, 0, 0, width, height, null);
      C'est bien sûr source qu'il faut dessiner et pas l'image img qu'on créé...
      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      g.drawImage(source, 0, 0, width, height, null);

      A noter qu'on peut faire plus simplement :
      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      1
      2
      3
      public static Image scaleImage(Image source, int width, int height) {
      	    return source.getScaledInstance(width, height, java.awt.Image.SCALE_AREA_AVERAGING);
      }
    2. Par ailleurs dans imageLabel = new JLabel("Label", scaledIcon, 10 );, le troisième argument est un alignement. Il vaut mieux utiliser une constante dédiée parce que 10 c'est moins parlant que la constante : imageLabel = new JLabel("Label", scaledIcon, JLabel.LEADING );
    3. Attention : ImageIcon icon = new ImageIcon("Image.jpg"); fait référence à un nom de fichier, situé dans le dossier de travail. Lors de la distribution du programme sous forme de jar unique (sans fichier à part, sinon c'est compliqué à distribuer), l'image se trouvera dans le jar, sous forme de ressource et non de fichier. Ce chemin ne sera donc plus valable. Il vaut mieux charger ce genre de fichier par leur URL de ressource. Par exemple, si le fichier est mis à la racine du package de la classe testImageLabel :

      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      private ImageIcon icon = new ImageIcon(testImageLabel.class.getResource("/Image.jpg"));
      ou si le fichier est mis dans le dossier du package de la classe (note l'utilisation d'un chemin relatif par opposition à un chemin absolu dans le cas précédent):
      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      private ImageIcon icon = new ImageIcon(testImageLabel.class.getResource("Image.jpg"));
    L'expression "ça marche pas" ne veut rien dire. Indiquez l'erreur, et/ou les comportements attendus et obtenus, et donnez un Exemple Complet Minimal qui permet de reproduire le problème.
    La plupart des réponses à vos questions sont déjà dans les FAQs ou les Tutoriels, ou peut-être dans une autre discussion : utilisez la recherche interne.
    Des questions sur Java : consultez le Forum Java. Des questions sur l'EDI Eclipse ou la plateforme Eclipse RCP : consultez le Forum Eclipse.
    Une question correctement posée et rédigée et vous aurez plus de chances de réponses adaptées et rapides.
    N'oubliez pas de mettre vos extraits de code entre balises CODE (Voir Mode d'emploi de l'éditeur de messages).
    Nouveau sur le forum ? Consultez Les Règles du Club.

  3. #3
    Membre à l'essai
    Homme Profil pro
    Ingénieur process
    Inscrit en
    Mars 2017
    Messages
    17
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Ingénieur process
    Secteur : Industrie

    Informations forums :
    Inscription : Mars 2017
    Messages : 17
    Points : 17
    Points
    17
    Par défaut
    Bonsoir Joel Drigo, et merci beaucoup pour cette réponse très complète !

    1. Merci pour m'avoir indiqué l'erreur. J'avoue avoir un peu de mal à comprendre le fonctionnement de cette méthode...
      Merci aussi pour la méthode plus simple .

    2. Oui, mieux vaut utiliser la constante dédiée, mais je ne savais pas trop comment fonctionne ce constructeur de JLabel. Je vais regarder ce que font les différentes constantes.

    3. Ça je n'ai pas bien compris. J'ai compris l'idée de charger le fichier sous forme de ressource, par contre, je n'ai pas compris la différence entre les deux codes que tu as mis...

  4. #4
    Modérateur
    Avatar de joel.drigo
    Homme Profil pro
    Ingénieur R&D - Développeur Java
    Inscrit en
    Septembre 2009
    Messages
    12 430
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D - Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2009
    Messages : 12 430
    Points : 29 131
    Points
    29 131
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par Miche59 Voir le message
    J'avoue avoir un peu de mal à comprendre le fonctionnement de cette méthode...
    Voici l'explication (j'ai ajouté des commentaires pour chaque ligne)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    public static Image scaleImage(Image source, int width, int height) {
    	    BufferedImage img = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB); // on crée une nouvelle image aux dimensions passées en paramètre (width & height), de type RGB avec couche alpha* (ceci n'est pas indispensable : ce serait mieux d'utiliser le type de l'image source, mais au moins ça fonctionne pour les images transparentes et non transparente)
    	    Graphics2D g = (Graphics2D)img.getGraphics(); // on crée un contexte graphique qui va nous permettre de dessiner dans la nouvelle image
    	    g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR); // on configure le type de d'algortihme de réduction, qui combine un aspect finesse/rectification des défauts dus à la réduction et un aspect vitesse de l'algorithme
    	    g.drawImage(source, 0, 0, width, height, null); // on dessine l'image source en position 0,0 (en haut à gauche) et de taille width & height, ce qui fait la réduction (ou l'agrandissement éventuellement selon les valeurs de width et height et les dimensions de l'image qu'on dessine)
    	    g.dispose(); // on libère les ressources mémoires mis en oeuvre pour le contexte graphique qui ne sont pas récupérables automatiquement par le mécanisme automatique de Java qu'on appelle le Garbage Collector.
    	    return img; // on retourne la nouvelle image
    	}
    * la couche alpha est ce qui va permettre de gérer la transparence. Les couleurs de chaque point sont définies par trois composantes, rouge, vert et bleu, plus une composant alpha, qui est une sorte de pourcentage de transparence.

    Citation Envoyé par Miche59 Voir le message
    mais je ne savais pas trop comment fonctionne ce constructeur de JLabel.
    La javadoc est indispensable pour ça.

    Citation Envoyé par Miche59 Voir le message
    Ça je n'ai pas bien compris. J'ai compris l'idée de charger le fichier sous forme de ressource, par contre, je n'ai pas compris la différence entre les deux codes que tu as mis...
    La différence, c'est le slash, au début du chemin du fichier.

    Le chemin de l'image passé en paramètre de getResource peut être :

    1. relatif au dossier du package de la classe (le dossier qui contient le fichier .class obtenu lors de la compilation du fichier .java).
    2. absolu par rapport à la racine des dossiers de packages .


    Pour indiquer un chemin absolu, on le fait juste commencer par un slash (/). S'il ne commence pas par un slash, alors il est considéré relatif. Si le fichier image est mis dans le même dossier que le fichier de classe, alors son chemin relatif est directement le nom du fichier. S'il y a beaucoup de ressources, c'est plus propre et plus simple à gérer que de mettre toutes les ressources dans un même dossier, par exemple appelé resources avec des sous-dossiers par exemple, images, sounds, videos, etc. Par exemple, si le fichier image.jpg est mis dans le dossier /resources/images, alors on pourra utiliser ce même chemin absolu pour n'importe quelle classe :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    getResource("/resources/images/image.jpg")
    L'expression "ça marche pas" ne veut rien dire. Indiquez l'erreur, et/ou les comportements attendus et obtenus, et donnez un Exemple Complet Minimal qui permet de reproduire le problème.
    La plupart des réponses à vos questions sont déjà dans les FAQs ou les Tutoriels, ou peut-être dans une autre discussion : utilisez la recherche interne.
    Des questions sur Java : consultez le Forum Java. Des questions sur l'EDI Eclipse ou la plateforme Eclipse RCP : consultez le Forum Eclipse.
    Une question correctement posée et rédigée et vous aurez plus de chances de réponses adaptées et rapides.
    N'oubliez pas de mettre vos extraits de code entre balises CODE (Voir Mode d'emploi de l'éditeur de messages).
    Nouveau sur le forum ? Consultez Les Règles du Club.

  5. #5
    Membre à l'essai
    Homme Profil pro
    Ingénieur process
    Inscrit en
    Mars 2017
    Messages
    17
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Ingénieur process
    Secteur : Industrie

    Informations forums :
    Inscription : Mars 2017
    Messages : 17
    Points : 17
    Points
    17
    Par défaut
    Merci Joel pour ces explications supplémentaires !

    C'est très utile ! Ça m'aide beaucoup à comprendre.

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

Discussions similaires

  1. Réponses: 1
    Dernier message: 16/02/2014, 14h53
  2. Réponses: 9
    Dernier message: 02/09/2013, 20h54
  3. Réponses: 1
    Dernier message: 04/04/2011, 17h12
  4. Réponses: 2
    Dernier message: 27/11/2006, 14h16
  5. [JFrame] affichage de component et d'image dans une JFrame
    Par Joeleclems dans le forum Agents de placement/Fenêtres
    Réponses: 8
    Dernier message: 08/10/2004, 16h17

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