précédent | suivant | table des matières

Image

Sommaire
  1. BufferedImage.
  2. Affichage d'une image.
  3. Lecture/écriture d'une image : ImageIO
  4. Traitement d'image
    1. ConvolveOp
    2. AffineTransformOp
    3. ColorConvertOp
    4. RescaleOp
    5. LookupOp
  5. Création d'image par calcul de pixels.
  6. VolatileImage
Hiérarchie image

(Démonstration)

1BufferedImage

La classe BufferedImage est dérivée de Image.

Les types d'image sont : 

BufferedImage

Une BufferedImage est composée

Un Raster est composé On obtient le modèle et le raster par les méthodes get.
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);
exemple

2Affichage 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.

3Lecture/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;
...
File f = new File("..."); try { bimg = ImageIO.read(f); }catch (IOException e) { ... }
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 :

4Traitement 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.

4 1Les 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);

42 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);

43Les 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

44Rescale.

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);

4 5Lookup.

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);

5Cré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.
  • pour les types TYPE_INT_RGB et TYPE_INT_ARGB, le tableau t sera un tableau de 3 ou 4 int contenant le rouge, puis le vert, puis le bleu et enfin la transparence.
  • pour le type TYPE_BYTE_GRAY le tableau t est un tableau de 1 entier qui contient la valeur de gris du pixel.
  • ...
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);
  }

6VolatileImage.

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 ... }


haut de la page