La gestion des images Bitmap
Bitmap, ça veut plus ou moins dire littéralement carte à points, ou carte à bit.
Et c’est bien ce genre d’informations que contient un fichier de ce type. Chaque pixel est enregistré dans
le bitmap. Aucune compression, que ce soit du type LZW ou par perte de données, n’est utilisée dans ce format.
C’est pourquoi la lecture et l’interprétation de ce genre de fichier reste relativement simple.
Un fichier bitmap est composé de 4 choses : les informations génerales, les informations d’en-tête,
la palette et les données.
Pour illustrer ceci, nous allons créér un lecteur d’images bitmap. Pour le faire, j’ai choisi un langage simple
et facilement compréhensible pour tous, même de ceux qui ne le connaissent pas : le QBasic. Vous pouvez télécharger
le code source de cet exemple ici :
Les informations génerales
Les informations génerales commencent avec le début du fichier, c’est à dire de l’octet 0 et s’achévent à
l’octet 10.
Voici ces informations :
| Offset (position) | Longueur (en octets) | Signification |
|---|---|---|
| 0 | 2 |
Normalement, il doit y avoir BM pour confirmer que l’image est bien un bitmap |
| 2 | 4 | Taille du fichier, sans la partie d’en-tête |
| 6 | 2 | Réservé. Normalement à zéro (0) |
| 8 | 2 | Réservé. Normalement à zéro (0) |
| 10 | 4 | Offset à partir du quel commencent les données. |
Hormis la confirmation du type d’image (Offset 0), ces informations sont rarement utilées. On passe généralement
directement au informations d’en-tête.
Les informations d’en-tête
Ces informations suivent directement les informations générales. Elles commencent donc au 14ème octet.
Elles donnent des renseignements sur l’image proprement dite : largeur, hauteur, nombres de couleurs…
| Offset (position) | Longueur (en octets) | Signification |
|---|---|---|
| 14 | 4 | Taille des information d’en-tête, soit 40, soit 12 |
| 18 | 4 | Largeur de l’image, en pixels |
| 22 | 4 | Hauteur de l’image, en pixels |
| 26 | 2 | Nombre de plan, doit être à 1 |
| 28 | 2 |
Nombre de bits par pixels. Les valeurs peuvent être 1, 4, 8 ou 24 |
| 30 | 4 |
Compression, doit normalement être à zéro. Sinon, c’est une image RLE |
| 34 | 4 | Taille de l’image, en octets |
| 38 | 4 | Largeur de l’image, dans une autre unité |
| 42 | 4 | Hauteur de l’image, dans une autre unité |
| 46 | 4 |
Nombre de couleurs utilisées par l’image. Si 0, alors toutes les couleurs sont utilisées. |
| 50 | 4 |
Nombre de couleurs importantes. Si 0, alors toutes les couleurs sont importantes. |
La palette
La palette représente les couleurs utilisées par l’image. Elles sont codées en RGB : Red, Green et
Blue. Selon les valeurs de ces composantes, on obtient différentes couleurs. Chaque composante peut varier de 0 à 255.
Attention! Pour les fichiers bitmap 24 bits, il n’y a pas de palette!
Voici comment obtenir ces couleurs :
| Offset (position) | Longueur (en octets) | Signification |
|---|---|---|
| 14 + Taille de l’en-tête | 1 | Intensité du Bleu de la couleur 0 |
| 14 + Taille de l’en-tête + 1 | 1 | Intensité du Vert de la couleur 0 |
| 14 + Taille de l’en-tête + 2 | 1 | Intensité du Rouge de la couleur 0 |
| 14 + Taille de l’en-tête + 3 | 1 | Inutilisé. Doit être à zéro. |
| 14 + Taille de l’en-tête + 4 | 1 | Intensité du Bleu de la couleur 1 |
| … | … | … |
Les données
Les données représentent l’index de la couleur de chaque pixel de l’image.
Elles commencent dans le coin inférieur gauche de l’image. Chaque donnée de plus est un pixel vers la droite.
Ensuite, tout dépend du nombre de bits par pixels de l’image :
| Bits par pixels | Représentation |
|---|---|
| 1 (monochrome) |
8 pixels (horizontaux) sont représentés dans un octet. Chaque bit de cet octet représente la couleur : 0 pour noir 1 pour blanc. |
| 4 (16 couleurs) |
Un octet représente 2 pixels de l’image. Les 4 bits de poids fort repésente la 1er couleur, et les 4 bits de poids faible la 2ème couleur de cet octet. |
| 8 (256 couleurs) | Le plus simple. Chaque octet représente la couleur d’un pixel. |
| 24 (16777216 couleurs) |
Comme dit plus haut, pour ce type d’image, il n’y a pas de palette. Chaque pixel est représenté par 3 octets. Chacun de ces 3 octets correspond à l’intensité d’une des 3 (!) composantes RGB du pixel. |
Exemple en QBasic
Voici un exemple de gestion des images bitmap avec un langage simple : le QBasic.
Attention! Cet exemple est MINIMUM. Il vous montre simplement la méthode pour exploiter
ce format d’image. Il n’est donc pas optimisé et est donc relativement lent.
DIM Octet AS STRING * 1 ' 1 Octet DIM Mot AS STRING * 2 ' 2 Octets DIM DMot AS STRING * 4 ' 4 Octets DIM HeadSize AS LONG ' Taille de l'en-tête DIM BWidth AS LONG ' Largeur de l'image DIM Bheight AS LONG ' Hauteur de l'image DIM bpp AS INTEGER ' Bits par pixels filename$ = "banniere.bmp" ' fichier à ouvrir SCREEN 13 ' Mode 256 couleurs CLS ' Attention en QBasic, le fichier commence à 1 et non pas à 0 ! OPEN filename$ FOR BINARY AS #1 ' Lecture des informations d'en-tête GET #1, 15, DMot HeadSize = CVL(DMot) GET #1, 19, DMot BWidth = CVL(DMot) GET #1, 23, DMot Bheight = CVL(DMot) GET #1, 29, Mot bpp = CVI(Mot) ' Lecture de la palette lengthpal = 4 * 2 ^ bpp StartPal = 15 + HeadSize EndPal = StartPal + lengthpal j = 0 FOR i = 0 TO lengthpal STEP 4 GET #1, i + StartPal, Octet bleu = INT(ASC(Octet) / 4) GET #1, i + StartPal + 1, Octet vert = INT(ASC(Octet) / 4) GET #1, i + StartPal + 2, Octet rouge = INT(ASC(Octet) / 4) PALETTE j, 65536 * bleu + 256 * vert + rouge j = j + 1 NEXT i ' Lecture des données y = Bheight DO x = 0 DO GET #1, , Octet Index = ASC(Octet) SELECT CASE bpp CASE 1 ' 1 bit FOR i = 0 TO 7 PSET (x + 7 - i, y), (Index AND 2 ^ i) / 2 ^ i NEXT i x = x + 8 CASE 4 ' 4 bits PSET (x, y), Index AND 15 PSET (x + 1, y), Index AND 240 / 16 x = x + 2 CASE 8 ' 8 bits PSET (x, y), Index x = x + 1 CASE 24 ' 24 bits END SELECT LOOP UNTIL x >= BWidth y = y - 1 LOOP UNTIL y <= 0 CLOSE #1
Fodrè penser à mettre un retour vers le haut! ce serè cool
je voudrai developer un logiciel de reconnaisance de forme. ton prog est genial, c’est exactement ca sof je n’est pas la totalité de limage??? juste un bout (1/4) en bas a gauche
Exusez moi, mais normalement c’est un cours d’algorithmique qu’on attend dans cette page, Non?
Merci pour ces précieuses informations qui m’ont permises de faire une classe bitmap en C++ qui sera bientôt mise en ligne sur http://iutbminformatique.free.fr/