Bitmap est une représentation d'image. (plan d'image)
Le format le plus populaire est le .bmp (bitmap) , qui est malheureusement la propriété de (c)microsoft.
https://fr.wikipedia.org/wiki/Windows_bitmap (bien décris ici)
Ce dernier nous autorise malgré tout à l'utiliser. Il reste un type de fichier un peu lourd et compliqué.
J'ai une préférence sur les formats libre pbm, pgm et ppm
Utilisable par gimp.
https://fr.wikipedia.org/wiki/Portable_pixmap
pbm , binaire map , Noir&Blanc
pgm, nuance de gris.
ppm, en couleurs 24bits
P1,P2,P3 sont de type ASCII complet. Le # signal un commentaire (dans l’entête)
Dans la wiki on nous conseille de ne jamais dépasser 70 caractères par ligne.
P4,P5,P6 seul l’entête est ASCII les données sont stockées en bit .. ou octet , appelé mode RAW (BRUT)
Noir et Blanc , 1 noir , 0 Blanc
Exemple de fichier P1: (ASCII total)
P1
8 8
0 0 0 1 1 0 0 0
0 0 0 1 1 0 0 0
0 0 0 1 1 0 0 0
1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1
0 0 0 1 1 0 0 0
0 0 0 1 1 0 0 0
0 0 0 1 1 0 0 0
work@bruno:~/work/croix$ hexdump -C croix.pbm
00000000 50 31 0a 38 20 38 0a 30 20 30 20 30 20 31 20 31 |P1.8 8.0 0 0 1 1|
00000010 20 30 20 30 20 30 0a 30 20 30 20 30 20 31 20 31 | 0 0 0.0 0 0 1 1|
*
00000030 20 30 20 30 20 30 0a 31 20 31 20 31 20 31 20 31 | 0 0 0.1 1 1 1 1|
00000040 20 31 20 31 20 31 0a 31 20 31 20 31 20 31 20 31 | 1 1 1.1 1 1 1 1|
00000050 20 31 20 31 20 31 0a 30 20 30 20 30 20 31 20 31 | 1 1 1.0 0 0 1 1|
00000060 20 30 20 30 20 30 0a 30 20 30 20 30 20 31 20 31 | 0 0 0.0 0 0 1 1|
*
00000087
On constate que chaque pixel est séparé d'un espace ou un retour a la ligne. (0x20 espace , 0x0a LF , retour à la ligne)
P1
8 8
0
0
0
1
1
0
0
0
0
0
0
1
....etc
Comme on ne peut pas dépasser 70 caractères par ligne on va préférer le LF (0x0a)
work@bruno:~/work/croix$ hexdump -C croix_lin.pbm
00000000 50 31 0a 38 20 38 0a 30 0a 30 0a 30 0a 31 0a 31 |P1.8 8.0.0.0.1.1|
00000010 0a 30 0a 30 0a 30 0a 30 0a 30 0a 30 0a 31 0a 31 |.0.0.0.0.0.0.1.1|
*
00000030 0a 30 0a 30 0a 30 0a 31 0a 31 0a 31 0a 31 0a 31 |.0.0.0.1.1.1.1.1|
00000040 0a 31 0a 31 0a 31 0a 31 0a 31 0a 31 0a 31 0a 31 |.1.1.1.1.1.1.1.1|
00000050 0a 31 0a 31 0a 31 0a 30 0a 30 0a 30 0a 31 0a 31 |.1.1.1.0.0.0.1.1|
00000060 0a 30 0a 30 0a 30 0a 30 0a 30 0a 30 0a 31 0a 31 |.0.0.0.0.0.0.1.1|
*
00000087
work@bruno:~/work/croix$ hexdump -C crx_raw.pbm
00000000 50 34 0a 38 20 38 0a 18 18 18 ff ff 18 18 18 |P4.8 8.........|
0000000f
L’entête est la même (P1 devenu P4)
8 8 , largeur (espace) hauteur , suivi d'un retour a la ligne.
Et la les données ne sont plus écrites en ASCII mais on va appeler ça en binaire.
0x18 = 0b00011000
0xFF = 0b111111111
On voit que ce format à l'avantage d'être moins gourmand en mémoire .
4 -rw-r--r-- 1 work work 135 févr. 4 16:14 croix.pbm
4 -rw-r--r-- 1 work work 15 févr. 4 16:26 crx_raw.pbm
Le premier est le P1 (croix.pbm) , et le P4 (crx_raw.pbm)
Attention le format P4 :
Un fichier pbm binaire a pour nombre magique P4. Dans les données binaires de l'image, les bits sont regroupés par 8 pour former un octet, les bits excédentaires à la fin d'une ligne sont ignorés.
Nuance de Gris
Tout est dit sur wikipedia sur les formats P2/5 ( pareil que P1/4)
Couleurs RVB
Pareil que P1/ P4
Tout est dit sur wikipedia sur les formats
Sauvegarde au format P4
int sauve_image_P4(char * titre)
{
int x,y;
unsigned char pds; /* connaitre le poid su bit */
unsigned char octet; /*contient le resultat de l'octet a ecrire */
octet=0;
pds=128;
fichier = fopen(titre,"w"); /* on ouvre le fichier en ecriture */
if (fichier == NULL)
{
printf(" Je n'ai pas reussi a ouvrir le fichier \n");
return(EXIT_FAILURE); /*on sort du programme erreur .. d'ouverture */
}
/* En tete de l image */
fprintf(fichier,"P4\n"); /* j'ecris dans le fichier */
fprintf(fichier,"%d %d\n",largeur,hauteur);
for (y = 0; y < hauteur; y++)
{
for (x= 0; x < largeur; x++)
{
if (image[x][y]=='1') octet =octet + pds;
//fprintf(fichier,"%c\n",image[x][y]);
pds=(unsigned char)(pds>>1);
if ((pds==0)|| (x==largeur-1))
{
fprintf(fichier,"%c",octet);
octet=0;
pds=128;
}
}
octet=0;
pds=128;
}
fclose(fichier); /* je ferme le fichier */
return EXIT_SUCCESS;
}