FAQ Java GUIConsultez toutes les FAQ
Nombre d'auteurs : 37, nombre de questions : 155, dernière mise à jour : 10 octobre 2015 Ajouter une question
Cette FAQ a été réalisée à partir des questions fréquemment posées sur les forums de http://www.developpez.com et de l'expérience personnelle des auteurs.
Nous tenons à souligner que cette FAQ ne garantit en aucun cas que les informations qu'elle propose sont correctes. Les auteurs font leur maximum, mais l'erreur est humaine. Cette FAQ ne prétend pas non plus être complète. Si vous trouvez une erreur, ou que vous souhaitez nous aider en devenant rédacteur, lisez ceci.
- Comment faire une capture d'écran ?
- Comment accéder à une image ?
- Comment enregistrer une image ?
- Comment connaître les types d'images que l'on peut lire ou écrire ?
- Comment mettre une image en fond de JFrame ?
- Comment convertir une image en une instance de BufferedImage ?
- Comment créer un objet de type Image depuis une BufferedImage ?
- Comment convertir une image couleurs en niveaux de gris ?
- Comment rendre floue une image ?
- Comment effectuer des transformations sur une image en mémoire ?
- Comment manipuler directement les pixels de mon image ?
- Qu'est-ce que l'encodage entier RGBA des couleurs d'une image ?
- Comment redimensionner une image ?
- Comment changer l'icône de la fenêtre de mon application ?
- Comment obtenir une Image de mon composant graphique ?
- Comment savoir si une image a des pixels transparents ?
- Comment dessiner et écrire sur une BufferedImage ?
- Comment combiner deux images ?
- Comment utiliser des images compatibles pour améliorer les performances et le rendu ?
- Comment modifier les pixels d'une image ?
La classe java.awt.Robot permet de faire facilement des captures d'écran.
Capture d'une zone :
Code java : | Sélectionner tout |
1 2 | Robot robot = new Robot(); BufferedImage image = robot.createScreenCapture(new Rectangle( 15, 15, 150, 150)); |
Code java : | Sélectionner tout |
1 2 3 | Robot robot = new Robot(); BufferedImage image = robot.createScreenCapture( new Rectangle(java.awt.Toolkit.getDefaultToolkit().getScreenSize()) ); |
Code java : | Sélectionner tout |
1 2 3 4 | Robot robot = new Robot(); BufferedImage image = robot.createScreenCapture( new Rectangle( frame.getX(), frame.getY(), frame.getWidth(), frame.getHeight() ) ); |
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 :
Code java : | Sélectionner tout |
1 2 | Image java.applet.Applet.getImage(URL url); Image java.applet.Applet.getImage(URL url, String name); |
Pour une application (Awt ou Swing), il faut utiliser les méthodes de la classe java.awt.Toolkit
Code java : | Sélectionner tout |
1 2 3 4 5 | /** 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); |
Code java : | Sélectionner tout |
BufferedImage image = ImageIO.read( /* File, URL ou InputStream */ );
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.
Code java : | Sélectionner tout |
java.net.URL url = getClass().getResource("chemin/nom.gif");
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://docs.oracle.com/javase/7/docs...ideTOC.fm.html.
JDK antérieur : Java ne permettait pas d'enregistrer une image aux formats GIF, PNG ou JPEG. Il va falloir faire appel à des classes extérieures permettant le codage de l'image.
- En Java 2, un 'package' est fourni pour enregistrer en JPEG (mais ne fait pas partie des librairies standard) : http://java.sun.com/products/jdk/1.2...w-summary.html
- Pour le GIF : http://www.acme.com/java/software/Ac...ifEncoder.html
- Pour le PNG, un encodeur est disponible dans le code source de Batik : http://xml.apache.org/batik
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 :
Code java : | Sélectionner tout |
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 | 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; } } |
Code java : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 | 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 |
Code java : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 | 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]); } |
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):
Code java : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 | 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); } } |
Code java : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 | 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); } } |
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.
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 :
Code java : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | 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. |
Comme BufferedImage étend image, on peut tout simplement employer une BufferImage en tant qu'Image.
Code java : | Sélectionner tout |
1 2 | BufferedImage buf = ...; Image image = buf; |
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.
Code java : | Sélectionner tout |
1 2 3 4 | ColorConvertOp op = new ColorConvertOp( ColorSpace.getInstance(ColorSpace.CS_GRAY), null); BufferedImage imageGrise = op.filter(bufferedImage,null); |
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...
Code java : | Sélectionner tout |
1 2 3 4 5 6 7 | 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); |
Il n'est pas possible d'effectuer de transformation directement sur une image mémoire, il faut créer une nouvelle image et dessiner la version transformée dans cette nouvelle image.
Code java : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 | /** 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(); |
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 bibliothèque graphique (DirectX ou autre), bref...
Lecture d'un pixel :
Code java : | Sélectionner tout |
1 2 3 4 5 6 7 8 | /** 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); |
Code java : | Sélectionner tout |
1 2 3 4 5 6 7 8 | /** Écriture d'un seul pixel : */ bufferedImage.setRGB(x,y,rgb); /** Écriture 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); |
Pour des raisons de performances, 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).
Code java : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 | /** 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 */ |
Redimensionnement d'une image :
Code java : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | /** * 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; } |
Code java : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | /** 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); } |
L'icône 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 tâches. 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'icône de la frame parente.
Code java : | Sélectionner tout |
1 2 | Image icone = Toolkit.getDefaultToolkit().getImage("./monImage.jpg"); maFenetre.setIconImage(icone); |
Une autre raison pour laquelle cette image n'apparaîtrait serait un problème au niveau de la transparence avec les images PNG qui ne sont pas gérées par tous les OS : certains OS vont l'afficher mais supprimer 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.
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 :
Code java : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 | 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; } |
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 quel que soit le type de l'image :
Code java : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | 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écupérer 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(); } |
Code java : | Sélectionner tout |
1 2 3 4 5 6 | // 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 gourmand en mémoire.
Pour combiner deux images, il suffit de dessiner 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 l'interpolation sur le Graphics2D. On peut ensuite tout simplement dessiner la deuxième image sur la première à l'endroit voulu.
Voici donc ce que ça donne :
Code java : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 | 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 ; } |
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éjà dans le bon format pour le périphérique d'affichage. Elles sont de type 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 simple. Il faut passer par la classe GraphicsConfiguration pour en obtenir une. Voici une méthode permettant de créer une nouvelle image compatible vide :
Code java : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | /** * 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); } |
Code java : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | /** * 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; } } |
Vous pouvez utiliser le code suivant :
Code Java : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 | private void imodifier_image() { BufferedImage image = new BufferedImage(largeur, hauteur, BufferedImage.TYPE_INT_ARGB); WritableRaster trame = image.getRaster(); int[] couleur = {Cr, Cv, Cb, Ca}; for (int x=0; x<largeur; x++) { for (int y=0; y<hauteur; y++) { trame.setPixel(x, y, couleur); } } } |
Attention, il est nécessaire de savoir qu'accélérer directement au Raster une BufferedImage annule toute accélération matérielle potentielle.
Proposer une nouvelle réponse sur la FAQ
Ce n'est pas l'endroit pour poser des questions, allez plutôt sur le forum de la rubrique pour çaLes sources présentées sur cette page sont libres de droits et vous pouvez les utiliser à votre convenance. Par contre, la page de présentation constitue une œuvre intellectuelle protégée par les droits d'auteur. Copyright © 2024 Developpez Developpez LLC. Tous droits réservés Developpez LLC. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez LLC. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.