En Java, il n'existe pas de type compact permettant de stocker des valeurs
de 0 à 255.
Si on privilégie la compacité, on peut utiliser le type
byte qui code les valeurs de -128 à 127.
Le gris moyen (valeur 128) est alors codé par le
byte -128 et le blanc (valeur 255) est codée par
le byte -1.
Si l'on doit faire de l'arithmétique sur les images ou, simplement,
préserver la relation d'ordre naturelle sur les pixels, il est
préférable d'utiliser un type plus "large".
Par exemple, le type short qui code les valeurs de -32768 à
32767 est généralement suffisant et il ne coûte que
deux octets par pixel.
À l'extrème, pour de l'arithmémique flottante, on
peut utiliser le type double qui coûte huits octets par pixel.
Pour l'instanciation, on utilisera l'une de ses sous-classes BytePixmap, ShortPixmap ou DoublePixmap. Ces sous-classes sont spécialisées par le type qui est utilisé pour le codage des pixels mais elles sont toutes définies selon le même modèle et, en particulier, elles ont 4 constructeurs. Par exemple :
public ShortPixmap(int w, int h, short[] pixels); public ShortPixmap(int w, int h); public ShortPixmap(Pixmap src); public ShortPixmap(String fileName);Le premier constructeur crée un ShortPixmap de dimensions w.h et dont le stockage des valeurs de pixels utilisera le tableau de short passé en paramètre.
Les dimensions d'un Pixmap sont accessibles dans ses champs
width et height.
Le champ size contient le produit des deux précédents.
Les valeurs des pixels sont accessibles dans le tableau data du
type approprié.
La référence au pixel de coordonnées (i,j)
(avec (0,0) en haut à gauche) est data[j*width+i].
Quelque soit le "type" d'un Pixmap, on peut obtenir une
copie de ses valeurs de pixels dans un nouveau tableau, par l'une des
méthodes (selon le type voulu) :
public byte[] getBytes(); public short[] getShorts(); public double[] getDoubles();Enfin, la méthode :
public void write(String fileName);permet de sauver un Pixmap dans un fichier PGM dont le nom est passé en paramètre.
public ByteRGBPixmap(int w, int h,
byte[] rPixels, byte[] gPixels, byte[] bPixels);
public ByteRGBPixmap(int w, int h);
public ByteRGBPixmap(Pixmap r, Pixmap g, Pixmap b);
public ByteRGBPixmap(RGBPixmap p);
public ByteRGBPixmap(String fileName);
Tous ces constructeurs créent 3 nouveaux BytePixmap
à partir des paramètres fournis.
Les dimensions d'un RGBPixmap sont accessibles dans ses champs
width et height.
Le champ size contient le produit des deux précédents.
Les 3 Pixmap composantes, de sous-classe appropriée, sont
accessibles par les champs r, g et b.
Par exemple, la référence à la composante rouge du pixel
de coordonnées (i,j) est r.data[j*width+i].
Enfin, la méthode :
public void write(String fileName);permet de sauver un RGBPixmap dans un fichier PPM dont le nom est passé en paramètre.
import java.io.*;
public class DemoPixmap {
public static void main(String[] args) {
BytePixmap p1;
try {
p1 = new BytePixmap(args[0]); // lecture du fichier
} catch (IOException e) { p1 = null; System.exit(0); }
for ( int i=0; i<p1.size; i++) // pour tous les pixels :
p1.data[i] = (byte)(255 - p1.data[i]); // oui cela marche tout de même !
ShortPixmap p2 = new ShortPixmap(p1); // clonage
for ( int i=0; i<p2.size; i++) // pour tous les pixels :
p2.data[i] = (short)(255 - p2.data[i]);// là c'est plus évident !
p1.write("neg_"+args[0]); // écriture de l'image en négatif
p2.write("copy_"+args[0]); // écriture de l'image d'origine
}
}
Voici un autre exemple de programme qui réalise une permutation des
trois composantes d'un fichier PPM :
import java.io.*;
public class DemoRGBPixmap {
public static void main(String[] args) {
ByteRGBPixmap rgb1;
try {
rgb1 = new ByteRGBPixmap(args[0]); // lecture du fichier
} catch (IOException e) { rgb1 = null; System.exit(0); }
ByteRGBPixmap rgb2 = new ByteRGBPixmap(rgb1.g, rgb1.b, rgb1.r);
rgb2.write("rot"+args[0]);
}
}
Et voici, de même, pour afficher un fichier PGM ou PPM dans un DrawingFrame de MacLib.
Pour toutes suggestions, commentaires ou remarques, email : Philippe.Chassignet@polytechnique.fr