précédent | suivant | table des matières
|
La classe BufferedImage est dérivée de Image.
Les types d'image sont :
Une BufferedImage est composée
TYPE_INT_ARGB : DirectColorModel: rmask=ff0000 gmask=ff00 bmask=ff amask=ff000000 TYPE_INT_RGB : DirectColorModel: rmask=ff0000 gmask=ff00 bmask=ff amask=0 TYPE_BYTE_GRAY : ColorModel: #pixelBits = 8 numComponents = 1 color space = java.awt.color.ICC_ColorSpace@32c41a transparency = 1 has alpha = false isAlphaPre = false
WritableRaster raster = image.getRaster(); ColorModel model = image.getColorModel();
Exemple : création d'une image constituée de la première diagonale rouge, l'autre diagonale violette et un cercle vert entouré de noir au milieu.
int l = 100; int lo = 10; // image avec transparence BufferedImage bi = new BufferedImage(l, l, BufferedImage.TYPE_INT_ARGB ); // on remplit en utilisant le tableau de pixels for(int i = 0; i<l; ++i) bi.setRGB(i, i, 0xFFFF0000); for(int i = 0; i<l; ++i) bi.setRGB(l-i-1, i, 0xFFFF00FF); // on remplit en utilisant Graphics Graphics g = bi.getGraphics(); g.setColor(Color.GREEN); g.fillOval(l/2-lo/2, l/2-lo/2, lo, lo); g.setColor(Color.BLACK); g.drawOval(l/2-lo/2, l/2-lo/2, lo, lo); |
Affichage d'une image
L'affichage d'une image se fait par la méthode drawImage de la classe Graphics, ou Graphics2D.
boolean drawImage(Image img, int x, int y, ImageObserver o) |
Affiche l'image img en x, y. Retourne true si l'image est réellement affichée, et false sinon : l'image n'est pas encore totalement chargée. L'observateur o est le composant qui sera notifié de la fin du chargement de l'image. |
boolean drawImage(Image img, int x, int y, Color f, ImageObserver o) |
Les pixels transparents ont f comme couleur de fond. |
boolea drawImage(Image img, int x, int y, int l, int h, ImageObserver o) |
Affiche l'image img en x, y, dans le rectangle de largeur l et de hauteur h. Retourne true si l'image est réellement affichée, et false sinon : l'image n'est pas encore totalement chargée. L'observateur o est le composant qui sera notifié de la fin du chargement de l'image. |
boolean drawImage(Image img, int x, int y, int l, int h, Color f, ImageObserver o) |
Les pixels transparents ont f comme couleur de fond. |
boolean drawImage(Image img, int dx1, int dy1, int dx2, int dy2, int dsx1, int sy1, int sx2, int sy2, ImageObserver o) |
Affiche la partie de l'image img désignée par le rectangle (sx1, sy1, sx2, sy2), dans le rectangle désigné par (dx1, dy1, dx2, dy2). Retourne true si l'image est réellement affichée, et false sinon : l'image n'est pas encore totalement chargée. l'observateur o est le composant qui sera notifié de la fin du chargement de l'image. |
boolean drawImage(Image img, int dx1, int dy1, int dx2, int dy2, int dsx1, int sy1, int sx2, int sy2, Color f, ImageObserver o) |
Les pixels transparents ont f comme couleur de fond. |
La classe Graphics2D ajoute les méthodes :
void drawImage(BufferedImage img, BufferedImageOp op, int x, int y) |
équivalent à :img1 = op.filter(img, null); drawImage(img1, new AffineTransform(1f, 0f, 0f, 1f, x, y), null); |
boolean drawImage(Image img, AffineTransform at, ImageObserver obs) |
Affiche l'image img transformée par at. |
L'interface ImageObserver est implémentée par Component. L'interface ImageObserver contient la méthode boolean imageUpdate(Image img, int infoflags, int x, int y, int largeur, int hauteur)
qui est la méthode appelée quand l'image
utilisée par l'observateur est enfin totalement disponible.
L'implémentation de cette méthode dans Component réalise un repaint() du composant.
Lecture/Ecriture d'image
La classe ImageIO permet de lire et d'écrire des images à partir de fichiers. Les formats d'images sont BMP, PNG, JPEG, et GIF en lecture seulement.
Lecture
BufferedImage bimg; |
Toolkit tk = Toolkit.getDefaultToolkit(); Image img = tk.getImage("..."); // l'image n'est pas encore chargée, // elle le sera à sa première utilisation // écrire la suite pour que l'image soit réellement chargée MediaTracker mt = new MediaTracker(this); mt.addImage(img, 0); try { mt.waitForID(0); ...// l'image est présente en mémoire } catch(InterruptedException e) {...} BufferedImage bimg = new BufferedImage( img.getWidth(),img.getHeight(),BufferedImage.TYPE_INT_RGB); bimg.createGraphics().drawImage(img, null, null); |
Ecriture
BufferedImage bimg; ... File f = new File("..."); try { if(!ImageIO.write(bimg, "png", f)) JOptionPane.showMessageDialog(null, "Ecriture impossible : "+format); }catch (IOException e) { ... } |
Les formats d'images en lecture ou en écriture qui sont utilisés par read et write, peuvent être obtenus par :
Traitement d'image
Java propose des opérations de traitement d’images (filtres).
L’interface est BufferedImageOp. Pour appliquer une opération est le filtrage on écrira :
BufferedImageOp operation = ...; operation.filter(imageSource, imageDest);
Il existe cinq classes qui implémentent BufferedImageOp :
Pour les 2 premiers filtres, les image source et destination doivent être différentes.
Les convolutions
Une convolution calcule la valeur pour chaque pixel en pondérant les couleurs des 9 (ou plus) pixels de son entourage. Les valeurs sont données dans un vecteur de flottants appelé noyau.
Flou, les 9 pixels ont même poids. | float[] flou = { 1f/9f, 1f/9f, 1f/9f, 1f/9f, 1f/9f, 1f/9f, 1f/9f, 1f/9f, 1f/9f}; |
Détection de contour, les voisins ont poids nul ou négatif. | float [] contour = { 0f, -1f, 0f, -1f, 4f, -1f, 0f, -1f, 0f}; |
Accentuation des couleurs.img | float [] accentuation = { 0f, -1f, 0f, 1f, 5f, -1f, 0f, -1f, 0f}; |
Repoussage | float [] repoussage = { -2f, -1f, 0f, -1f, 1f, 1f, 0f,1f, 2f}; |
Le constructeur a un deuxième paramètre qui vaut :
Exemple :
Kernel kernel = new Kernel(3, 3, flou); ConvolveOp cOp = new ConvolveOp(kernel, ConvolveOp.EDGE_ZERO_FILL, null); cOp.filter(bmg,imgDest);
Les transformations affines.
Pour faire une transformation affine sur une image, on utilise lesmêmes transformations affines que Graphics2D.
Exemple : une rotation autour du centre de l'image plus une homothétie :
AffineTransform at = new AffineTransform(); at.translate(img.getWidth(this)/2, img.getHeight(this)/2); at.rotate(angle); at.scale(chx, chy); at.translate(img.getWidth(this)/2, img.getHeight(this)/2); AffineTransformOp atOp = new AffineTransformOp(at, AffineTransformOp.TYPE_BICUBIC); BufferedImage bimgDest = new BufferedImage(img.getWidth(this), img.getHeight(this),BufferedImage.TYPE_INT_RGB); atOp.filter(bimg, bimgDest);
Les conversion de couleur.
Pour passer l'image en noir et blanc on écrirait :
ColorSpace gris = ColorSpace.getInstance(ColorSpace.CS_GRAY);
ColorSpace couleur = ColorSpace.getInstance(ColorSpace.CS_sRGB);
ColorConvertOp ccOp = new ColorConvertOp(couleur, gris, null);
ccOp.filter(bimg, bimg); // source et destination peuvent être identiques pour ColorConvert
Rescale.
Les opérations rescale modifient les valeurs des composantes RGB de chaque pixel : c' = c*m+d Cette opération permet d'éclaircir ou d'assombrir une image, en gardant ou non le contraste.
RescaleOp scOp = new RescaleOp(m, d, null); scOp.filter(bimg, bimg);
Chaque composante de chaque pixel est remplacée par une valeur se trouvant dans une table.
short [][] tab = new short [3][256];
...
// remplir tab.
LookupTable lut = new ShortLookupTable(0, tab);
LookupOp luOp = new LookupOp(lut, null);
luOp.filter(bimg, bimg);
Création d'images.
Le Raster d'une BufferedImage est un tableau à deux dimensions de pixels. Ces pixels peuvent être lus ou modifiés par :
la méthode setRGB de BufferedImage | BufferedImage img; ... img.setRGB(i, j, r<<8|v<<8|b); |
la méthode getRGB de BufferedImage | BufferedImage img; ... int c = img.getRGB(i, j); |
Ou les méthodes setPixel de la classe WritableRaster :
void setPixel(int x, int y, double[] t) void setPixel(int x, int y, float[] t) void setPixel(int x, int y, int[] t) |
Affecte le pixel d'indices i et j de la valeur de trouvant dans le tableau t.
|
void setPixels(int x, int y, int l int h, double[] t) void setPixels(int x, int y, int l, int h, float[] t) void setPixels(int x, int y, int l, int h, int[] t) |
affecte les pixels du rectangle donné, avec les valeurs se trouvant dans le tableau t. |
BufferedImage img = new BufferedImage(largeur, hauteur, BufferedImage.TYPE_INT_RGB); int [] t = new int[3]; for( int i = 0; i< largeur; ++i) for(int j = 0; j<hauteur; ++j){ t[0] = calculerRouge() t[1] = calculerVert(); t[2] = calculerBleu(); img.getRaster().setPixel(i, j, t); }
VolatileImage.
Une VolatileImage est une image stockée dans la mémoire de la carte vidéo, et qui utilise le matériel de la carte vidéo pour s'afficher : ceci entraine un gain de temps.
Création de VolatileImage :
Certaines cartes vidéo ont une mémoire très rapide mais qui peut être effacée sans préavis. Il y a donc deux stades d'accélérations :
Il y a deux problèmes qui peuvent arriver lorsque l'on utilise des VolatileImage :
Le code pour créer une image volatile est :
private VolatileImage image; void paintComponent(Graphics g) { super.paintComponent(g); if (image==null) // création de l'image image = createVolatileImage(getWidth(), getHeight()); do { int code = image.validate(getGraphicsConfiguration()); switch(code) { case VolatileImage.IMAGE_INCOMPATIBLE: image = createVolatileImage(getWidth(), getHeight()); case VolatileImage.IMAGE_RESTORED: reCreer(); // redessiner l'image } if (image.validate(getGraphicsConfiguration())==VolatileImage.IMAGE_OK) g.drawImage(image, 0, 0, this); } while (image.contentsLost()); }
void reCreer() { Graphics2D g = image.createGraphics(); / dessiner l'image ... }