FAQ Java GUIConsultez toutes les FAQ

Nombre d'auteurs : 51, nombre de questions : 152, dernière mise à jour : 29 juin 2013 

 
OuvrirSommaireLes images

La classe java.awt.Robot permet de faire facilement des captures d'écran.

Capture d'une zone :

 
Sélectionnez
Robot robot = new Robot();
BufferedImage image = robot.createScreenCapture(new Rectangle( 15, 15, 150, 150));

Capture de tout l'écran :

 
Sélectionnez
Robot robot = new Robot();
BufferedImage image = robot.createScreenCapture(
         new Rectangle(java.awt.Toolkit.getDefaultToolkit().getScreenSize()) );

Capture d'une fenêtre :

 
Sélectionnez
Robot robot = new Robot();
BufferedImage image = robot.createScreenCapture(
        new Rectangle( frame.getX(), frame.getY(), frame.getWidth(), frame.getHeight() )
        );
Créé le 12 avril 2002  par Clément Cunin

Lien : Comment connaître la taille de l'écran ?

Type de fichier supporté :
GIF, JPEG, PNG, BMP et WBMP. Pour lire des images encodées dans d'autres formats, vous devez utiliser une bibliothèque externe.

Dans un applet :
La classe Applet fournit tout le nécessaire pour la lecture d'image :

 
Sélectionnez
Image java.applet.Applet.getImage(URL url);
Image java.applet.Applet.getImage(URL url, String name);

Dans une application :
Pour une application (Awt ou Swing), il faut utiliser les méthodes de la classe java.awt.Toolkit

Avec Toolkit (limité à GIF, JPEG, PNG)
Sélectionnez
/** Accès au toolkit : */
java.awt.Toolkit toolkit = java.awt.Toolkit.getDefaultToolkit();
/** lecture de l'image : */
Image image = toolkit.getImage("fichier");
Image image = toolkit.getImage(url);
Avec Toolkit (supporte GIF, JPEG, PNG, BMP et WBMP)
Sélectionnez
BufferedImage image = ImageIO.read( /* File, URL ou InputStream */ );

A noter qu'avec ImageIO, les images sont complètement chargées lors du retour de la méthode read(), alors que les images renvoyées par le Toolkit sont chargées en arrière plan.

Dans un Jar :
Si l'image se trouve dans une archive, le plus simple est de laisser le ClassLoader trouver le fichier. Cette solution est valable que l'image se trouve ou non dans une archive, il est donc préférable de toujours utiliser le ClassLoader afin de limiter les problèmes lors du déploiement de l'application/applet.

 
Sélectionnez
java.net.URL url = getClass().getResource("chemin/nom.gif");
Mis à jour le 3 mai 2002  par Clément Cunin

JDK 1.4 :Le JDK1.4 introduit le "imaging I/O framework" qui permet d'écrire des images dans la majorité des formats courants : http://java.sun.com/j2se/1.4/docs/guide/imageio/index.html

JDK antérieur :Java ne permettait pas d'enregistrer une image au format GIF, PNG ou JPEG. Il va falloir faire appel à des classes extérieures permettant le codage de l'image.

Mis à jour le 6 juin 2002  par Jean-Baptiste Bugeaud

Lien : Une page très intéressante sur les différentes librairies disponibles pour la lecture et l'écriture des images.

La classe ImageIO du package javax.imageio permet l'accès à ces informations. On peut ainsi connaître les types d'images que l'on peut lire ou écrire en fonction du nom du format, du type MIME ou du suffixe d'un fichier. Voici un exemple :

 
Sélectionnez
import javax.imageio.*; 
public class FormatsImages{
public static boolean canRead(String format){
   boolean type = ImageIO.getImageReadersByFormatName(format).hasNext();
   boolean mime = ImageIO.getImageReadersByMIMEType(format).hasNext();
   boolean suffixe = ImageIO.getImageReadersBySuffix(format).hasNext();
   String infos = "Informations lecture "+format+" : ";
   infos+="Format image = "+type+", ";
   infos+="MIME = "+mime+", ";
   infos+="Suffixe fichier = "+suffixe;
   System.out.println(infos);
   return type||mime||suffixe;
}
public static boolean canWrite(String format){
   boolean type = ImageIO.getImageWritersByFormatName(format).hasNext();
   boolean mime = ImageIO.getImageWritersByMIMEType(format).hasNext();
   boolean suffixe = ImageIO.getImageWritersBySuffix(format).hasNext();
   String infos = "Informations écriture "+format+" : ";
   infos+="Format image = "+type+", ";
   infos+="MIME = "+mime+", ";
   infos+="Suffixe fichier = "+suffixe;
   System.out.println(infos);
   return type||mime||suffixe;
}
}

Vous pouvez utiliser ces deux méthodes statiques pour vérifier n'importe quel format.

 
Sélectionnez
canRead("gif");
canRead("jpg");
canRead("bmp");
canRead("image/jpeg");
//quelques vérifications sur les possibilités de lecture
canWrite("gif");
canWrite("jpg");
canWrite("bmp");
canWrite("image/jpeg");
//quelques vérifications sur les possibilités d'écriture

Vous pouvez avoir accès à tous les types d'images que vous pouvez lire ou écrire grâce aux méthodes getReaderFormatNames et getWriterFormatNames. les mêmes méthodes sont disponibles pour les types MIME.

 
Sélectionnez
String[] formatsLecture = ImageIO.getReaderFormatNames();  
String[] formatsEcriture = ImageIO.getWriterFormatNames();
//affichage des formats d'images lisibles
System.out.println("Formats d'images disponibles en lecture");
for(int i=0;i<formatsLecture.length;i++){
   System.out.println(formatsLecture[i]);
}  
System.out.println("Formats d'images disponibles en écriture");
for(int i=0;i<formatsEcriture.length;i++){
   System.out.println(formatsEcriture[i]);
}  
 
Créé le 12 août 2004  par Ioan Calapodescu

Lien : Comment accéder à une image ?
Lien : Comment enregistrer une image ?

L'ajout d'image en fond de composant n'est pas possible avec les classes de base de Swing. Heureusement, la réalisation d'une telle classe n'est pas compliquée, il suffit de créer un nouveau composant héritant de JComponent et de surcharger la méthode paintComponent.

La méthode paintComponent(Graphique g) est chargée de dessiner le composant ; les composants fils seront dessinés par dessus plus tard.

Exemple (Swing):

 
Sélectionnez
public class MonPanel extends JComponent {
 
        /** variable de classe contenant l'image à afficher en fond */
        private Image bg;
 
        /** Surcharge de la fonction paintComponent() pour afficher notre image */
         public void paintComponent(Graphics g) {
                g.drawImage(bg,0,0,null);
        } 
} 

Exemple (AWT):

 
Sélectionnez
public class MonPanel {
 
        /** variable de classe contenant l'image à afficher en fond */
        private Image bg;
 
        /** Surcharge de la fonction paint() pour afficher notre image */
         public void paint(Graphics g) {
                g.drawImage(bg,0,0,null);
        } 
} 

Note :Vous pouvez placer le composant dans la JFrame en utilisant la méthode setContentPane(moncomposant).

Fichier joint :Vous trouvez, dans les liens ci-dessous, un exemple complet d'implémentation d'un tel objet, permettant d'afficher l'image en mosaïque ou centrée.

Mis à jour le 15 novembre 2008  par Clément Cunin

Téléchargement : Extension de JPanel pour afficher des images en arrière-plan.
Téléchargement : Exemple d'utilisation de la classe.

Beaucoup d'opérations de manipulation d'image ne travaillent que sur des java.awt.image.BufferedImage. La vie étant parfois mal faite, il est courant de trouver dans l'API des méthodes nous retournant des images, mais assez rarement des bufferedImages, il nous faut donc convertir ces images... Voici une méthode qui s'occupe de tout :

 
Sélectionnez
BufferedImage toBufferedImage(Image image) {
        /** On test si l'image n'est pas déja une instance de BufferedImage */
        if( image instanceof BufferedImage ) {
                return( (BufferedImage)image );
        } else {
                /** On s'assure que l'image est complètement chargée */
                image = new ImageIcon(image).getImage();
 
                /** On crée la nouvelle image */
                BufferedImage bufferedImage = new BufferedImage(
                            image.getWidth(null),
                            image.getHeight(null),
                            BufferedImage.TYPE_INT_RGB );
 
                Graphics g = bufferedImage.createGraphics();
                g.drawImage(image,0,0,null);
                g.dispose();
 
                return( bufferedImage );
        } 
}

Cette façon ne préserve pas la transparence de l'image de base.

Mis à jour le 15 novembre 2008  par Clément Cunin

Comme BufferedImage étend image, on peut tout simplement employer une BufferImage en tant qu'Image.

 
Sélectionnez

	BufferedImage buf = ...;
	Image image = buf;
Mis à jour le 3 février 2007  par Seigne David

Les modifications de couleur d'une image sont assurées par la classe java.awt.image.ColorConvertOp qui travaille à partir de java.awt.image.BufferedImage.

 
Sélectionnez
ColorConvertOp op = new ColorConvertOp(
                                             ColorSpace.getInstance(ColorSpace.CS_GRAY),
                                             null);
BufferedImage imageGrise = op.filter(bufferedImage,null);
Créé le 10 novembre 2002  par Clément Cunin

Lien : Comment convertir une image en une instance de BufferedImage ?

L'algorithme permettant de rendre une image floue travaille très simplement : la couleur d'un pixel est calculée en faisant la moyenne pondérée de sa couleur et de celles de ses voisins. Il suffit de modifier les coefficients et le nombre de voisins pour intervenir sur le résultat, plus le poids des voisins est important, plus l'image sera floue. De plus, on peut choisir le poids d'un voisin en fonction de sa position, ce qui permet d'attribuer des poids différents et d'obtenir des résultats surprenants...

 
Sélectionnez
float[ ] matrice = {
    0.1f, 0.1f, 0.1f,
    0.1f, 0.2f, 0.1f,
    0.1f, 0.1f, 0.1f
};
BufferedImageOp op = new ConvolveOp(new Kernel(3,3,matrice));
BufferedImage nouvelleImage = op.filter(bufferedImage, null);
Mis à jour le 15 novembre 2008  par Clément Cunin

Lien : Comment convertir une image en une instance de BufferedImage ?

Il n'est pas possible d'effectuer de transformation directement sur une image mémoire, il faut créer un nouvelle image et dessiner la version transformée dans cette nouvelle image.

 
Sélectionnez
/** Création d'une nouvelle image */
BufferedImage nouvelleImage = new BufferedImage(
                                          imageSource.getWidth(),
                                          imageSource.getHeight(),
                                          imageSource.getType());
Graphics2D g2d = nouvelleImage.createGraphics();
/** préparation de la transformation */
AffineTransform at = new AffineTransform();
at.rotate(angle,x,y);
 
g2d.drawImage(imageSource,at,null);
g2d.dispose();
Créé le 27 janvier 2003  par Clément Cunin

C'est à mon avis une assez mauvaise idée. Les méthodes de la classe java.awt.Graphics sont généralement des appels directs des fonctions de la carte vidéo ou d'une bibliotheque graphique (DirectX ou autre), bref.

Lecture d'un pixel :

 
Sélectionnez
/** Lecture d'un seul pixel : */
int rgb = bufferedImage.getRGB(x,y);
 
/** Lecture de tous les pixels : */
int w = bufferedImage.getWidth();
int h = bufferedImage.getHeight();
int[] rgbs = new int[w*h]; /** on crée l'espace neccessaire */
bufferedImage.getRGB(0,0,w,h,rgbs,0,w);

Ecriture d'un pixel :

 
Sélectionnez
/** Ecriture d'un seul pixel : */
bufferedImage.setRGB(x,y,rgb);
 
/** Ecriture de tous les pixels : */
int w = bufferedImage.getWidth();
int h = bufferedImage.getHeight();
int[] rgbs = new int[w*h];
bufferedImage.setRGB(0,0,w,h,rgbs,0,w);
Créé le 27 janvier 2003  par Clément Cunin

Lien : Qu'est-ce que l'encodage entier RGBA des couleurs d'une image ?

Pour des raisons de performance on utilise un seul entier pour coder les trois couleurs primaires (rouge, vert, bleu) et la composante alpha (le niveau de transparence). Chaque composante est codée sur 8 bits (bleu 0-7, vert 8-15, rouge 16-23, alpha 24-31).

 
Sélectionnez
/** Lecture manuelle des composantes : */
int rgb = bufferedImage.getRGB(x,y);
int alpha = (rgb >>24 ) & 0xFF;
int rouge = (rgb >>16 ) & 0xFF;
int vert = (rgb >> 8 ) & 0xFF;
int bleu = rgb & 0xFF;
 
/** Construction d'un pixel : */
int rgb = (alpha<<24)+(rouge<<16)+(vert<<8)+bleu;
/** Les composantes doivent obligatoirement être comprises dans l'intervalle 0-255 */
Créé le 1er mars 2003  par Clément Cunin

Lien : Comment manipuler directement les pixels de mon image ?

Redimensionnemant d'une image :

 
Sélectionnez
/** 
 * Redimensionne une image.
 * 
 * @param source Image à redimensionner.
 * @param width Largeur de l'image cible.
 * @param height Hauteur de l'image cible.
 * @return Image redimensionnée.
 */
public static Image scale(Image source, int width, int height) {
    /* On crée une nouvelle image aux bonnes dimensions. */
    BufferedImage buf = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
 
    /* On dessine sur le Graphics de l'image bufferisée. */
    Graphics2D g = buf.createGraphics();
    g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
    g.drawImage(source, 0, 0, width, height, null);
    g.dispose();
 
    /* On retourne l'image bufferisée, qui est une image. */
    return buf;
}

Redimensionnemant d'une BufferedImage :

 
Sélectionnez
/** 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);
 
} 

Note :Un coefficient supérieur à 1 correspond à un agrandissement, un coefficient inférieur à 1 correspond à une réduction.

Mis à jour le 3 février 2007  par Pierre-Yves Varoux

L'icone d'une application apparaît à divers endroits en fonction du système d'exploitation. Sous windows, on la retrouve en haut à gauche de la fenêtre, et dans la barre des taches. Par défaut, il s'agit de la tasse de café de Java. Il est très facile de la personnaliser en utilisant la méthode setIconImage(java.awt.Image) des classes javax.swing.JFrame.
Cette méthode n'est pas disponible pour la classe JDialog, les dialogues utilisent automatiquement l'icone de la frame parente.

 
Sélectionnez
Image icone = Toolkit.getDefaultToolkit().getImage("./monImage.jpg");
maFenetre.setIconImage(icone);

Si l'image n'apparaît pas, c'est certainement que le paramètre image a une valeur 'null'.

Une autre raison pour laquelle cette image n'apparaitrait serait un problème au niveau de la transparence avec les images PNG qui ne sont pas gérés par tous les OS, certains OS vont l'afficher mais supprimmer la transparence et d'autres ne pas l'afficher.
De plus, certains OS ne supportent simplement pas les images de type PNG, transparence ou non.

Mis à jour le 15 novembre 2008  par Clément Cunin, bulbo

Lien : Comment accéder à une image ?

La classe Component a la capacité de peindre l'intégralité de son contenu dans un Graphics, grâce à la méthode paintAll.

Voici une méthode permettant de récuperer l'Image d'un Component quelconque :

 
Sélectionnez

public Image getImage(Component component){
   if(component==null){return null;}
   int width = component.getWidth();
   int height = component.getHeight();
   BufferedImage image = new BufferedImage(width, height, 
                                             BufferedImage.TYPE_INT_RGB);
   Graphics2D g = image.createGraphics();
   component.paintAll(g);
   g.dispose();
   return image;
}
Créé le 9 septembre 2004  par Ioan Calapodescu

Cette information est relativement simple à obtenir si l'on travaille avec une instance de BufferedImage. Si c'est le cas, on peut directement demander au ColorModel de l'image de nous donner l'information. Dans le cas contraire, on est obligé de passer par un PixelGrabber.

Voici une méthode permettant de récuperer cette information quelque soit le type de l'image :

 
Sélectionnez

public boolean alphaLayer(Image image){
   ColorModel modele = null; 
   if(image instanceof BufferedImage){
      // si on a affaire à une BufferedImage on regarde son ColorModel
      BufferedImage bi = (BufferedImage)image;
      modele = bi.getColorModel(); 
   }else {
     // on traite l'image pixel par pixel afin de récuperer un ColorModel
      PixelGrabber pg = new PixelGrabber(image, 0, 0, 1, 1, false); 
      try{
       // on découpe donc l'image pixel par pixel
         pg.grabPixels(); 
      }catch (InterruptedException e) {
         e.printStackTrace();
      } 
      modele = pg.getColorModel();
   }
   return modele.hasAlpha(); 
}
Créé le 9 septembre 2004  par Seigne David
 
Sélectionnez
// on crée auparavant la BufferedImage avec le nom bi
 
Graphics2D g2d = bi.createGraphics(); // on récupère le contexte graphique de la BufferedImage   
g2d.setColor( Color.red ); // on met l'état de couleur rouge à la BufferedImage
g2d.fillOval( 30, 30, 100, 100 ); // on dessine un cercle de centre x=30 y=30 et de rayon=100
g2d.dispose(); //on libère la mémoire utilisée pour le contexte graphique


Si vous ne faites pas de dispose() sur le contexte graphique et que vous rafraichissiez beaucoup celui-ci durant l'utilisation du programme, votre programme sera de plus en plus gourmant en mémoire.

Créé le 3 avril 2005  par Seigne David

Pour combiner 2 images, il suffit de dessinner la deuxième image sur la première image. Pour cela, il faut récupérer le Graphics2D de la première image et ensuite configurer l'anti-aliasing et la interpolation sur le Graphics2D. On peut ensuite tout simplement dessinner la deuxième image sur la première à l'endroit voulu.

Voilà donc ce que ça donne :

 
Sélectionnez
public static BufferedImage addImage(BufferedImage image1, BufferedImage image2){
	Graphics2D g2d = image1.createGraphics();
	g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
	                RenderingHints.VALUE_ANTIALIAS_ON);
	g2d.setRenderingHint(RenderingHints.KEY_ALPHA_INTERPOLATION,
	                RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY);
 
	g2d.drawImage(image2, 0, 0, null);
 
	g2d.dispose();
 
	return image1 ;
}
Créé le 25 mai 2007  par Zedros, Baptiste Wicht

Lorsque vous utilisez des BufferedImage, il est important d'utiliser ce qu'on nomme des images compatibles.

Qu'est-ce que c'est ?

Ce sont des images qui sont déja dans le bon format pour le périphérique d'affichage. Elles sont de types BufferedImage et ont certains avantages au niveau de la performance.

Qu'est-ce que ça change ?

Ce type d'image étant directement adapté au rendu sur le périphérique d'affichage utilisé, elles nécessitent moins de code Java2D pour être affichées.

Comment les utiliser ?

L'utilisation de telles images est très simples. Il faut passer par la classe GraphicsConfiguration pour en obtenir une. Voici une méthode permettant de créer une nouvelle image compatible vide :

Créer une nouvelle image compatible
Sélectionnez
/**
 * Create a compatible image.
 *
 * @param width  The width.
 * @param height The height.
 * @param type   The type of the image.
 * @return A compatible image.
 */
private static BufferedImage createCompatibleImage(int width, int height, int type) {
    GraphicsConfiguration gc = GraphicsEnvironment.
            getLocalGraphicsEnvironment().getDefaultScreenDevice().getDefaultConfiguration();
 
    return gc.createCompatibleImage(width, height, type);
}

Et voici une méthode permettant de convertir une image existante en image compatible :

Rendre une image existante compatible
Sélectionnez
/**
 * 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;
    }
}

On commence par tester si le modèle de couleur de l'image n'est pas déja le bon pour ne pas faire de travail dans le vide. Ensuite, on créer une nouvelle image compatible et on dessinne l'ancienne image sur la nouvelle.

Créé le 6 juin 2009  par Baptiste Wicht
Les codes sources présentés sur cette page sont libres de droits et vous pouvez les utiliser à votre convenance. Pour le reste, ce document constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Ce document issu de http://www.developpez.com est soumis à deux licences, en fonction des contributeurs : - Les contributions de Clément Cunin et Johann Heymes sont soumises aux termes de la la licence GNU FDL traduite en français ici. Permission vous est donnée de distribuer, modifier des copies des contributions de Clément Cunin et Johann Heymes tant que cette note apparaît clairement : "Ce document issu de http://www.developpez.com est soumis à la licence GNU FDL traduite en français ici. Permission vous est donnée de distribuer, modifier des copies de cette page tant que cette note apparaît clairement". - Pour ce qui est des autres contributions : Copyright © 2004 - 2009 Developpez LLC : Tous droits réservés Developpez LLC. Aucune reproduction ne peut en être faite sans l'autorisation expresse de Developpez LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts. Cette page est déposée à la SACD.