Formatul de imagine BMP

Scris dePaul Bourke
Iulie 1998


Introducere

Fișierele BMP sunt un format de fișier istoric (dar încă folosit în mod obișnuit) pentru sistemul de operare istoric (dar utilizat în continuare) denumit “Windows”. Imaginile BMP pot varia de la alb-negru (1 bit pe pixel) până la 24 de biți (16,7 milioane de culori). În timp ce imaginile pot fi comprimate, acest lucru este rar folosit în practică și nu va fi discutat în detaliu aici.

Structura

Un fișier BMP este format din 3 sau 4 părți, după cum se arată în diagrama din dreapta. Prima parte este un antet, acesta este urmat de o secțiune de informare, dacă imaginea este indexată de culoare, atunci paleta urmează, iar ultima este data pixelilor. Poziția datelor imaginii cu privire la sartul fișierului este inclusă în antet. Informațiile cum ar fi lățimea și înălțimea imaginii, tipul de compresie, numărul de culori sunt cuprinse în antetul informațiilor.

Antet

Antetul este alcătuit din următoarele câmpuri. Rețineți că suntem asumați scurt int de 2 octeți, int de 4 octeți și lung int de 8 octeți. Mai mult, presupunem ordonarea byte ca pentru mașinile tipice (Intel). Antetul are lungimea de 14 octeți.

typedef struct {
   unsigned short int type;                 /* Magic identifier            */
   unsigned int size;                       /* File size in bytes          */
   unsigned short int reserved1, reserved2;
   unsigned int offset;                     /* Offset to image data, bytes */
} HEADER;

Câmpurile utile din această structură sunt câmpul de tip (trebuie să fie “BM”) care este o verificare simplă a faptului că acesta este probabil un fișier BMP legitim și câmpul de offset care dă numărul de octeți înainte de datele efective ale pixelilor este relativ la începutul fișierului). Rețineți că acest struct nu este un multiplu de 4 octeți pentru acele mașini / compilatoare care ar putea să presupună acest lucru, aceste mașini vor împacheta în general această structură cu 2 octeți la 16, ceea ce va alinia viitoarele apeluri fread () – să fie avertizat.

Informație

Datele de imagine care urmează au o lungime de 40 de octeți, este descrisă în structura dată mai jos. Câmpurile cele mai interesate de mai jos sunt lățimea și înălțimea imaginii, numărul de biți per pixel (ar trebui să fie 1, 4, 8 sau 24), numărul de planuri (presupuse a fi 1 aici) și tipul de comprimare fi 0 aici).

typedef struct {
   unsigned int size;               /* Header size in bytes      */
   int width,height;                /* Width and height of image */
   unsigned short int planes;       /* Number of colour planes   */
   unsigned short int bits;         /* Bits per pixel            */
   unsigned int compression;        /* Compression type          */
   unsigned int imagesize;          /* Image size in bytes       */
   int xresolution,yresolution;     /* Pixels per meter          */
   unsigned int ncolours;           /* Number of colours         */
   unsigned int importantcolours;   /* Important colours         */
} INFOHEADER;

Tipurile de compresie acceptate de BMP sunt enumerate mai jos:

  • 0 – fără compresie
  • Cod de lungime de rulare 1 – 8 biți
  • 2 – 4 biți cod de lungime de rulare
  • 3 – RGB bitmap cu masca
Doar tastați 0 (nu va fi discutată aici nicio comprimare.

Date de imagine de 24 biți

Cele mai simple date pe care trebuie să le citiți sunt imaginile color 24 de biți adevărate. În acest caz, datele de imagine urmează imediat după antetul de informații, adică nu există paletă de culori. Se compune din trei octeți per pixel în ordine b, g, r. Fiecare octet dă saturația pentru acea componentă de culoare, 0 pentru negru și 1 pentru alb (complet saturat).

Date de culoare indexate

Dacă imaginea este indexată de culoare, imediat după antetul de informații va fi un tabel de culori infoheader.ncolours, fiecare dintre cele 4 octeți. Primele trei octeți corespund componentelor b, g, r, ultimul octet este rezervat / neutilizat, dar ar putea reprezenta în mod evident canalul alfa. Pentru imaginile de 8 biți în tonuri de gri, acest index de culoare va fi, în general, doar o rampă de gri. Dacă faci sumele … atunci lungimea antetului plus lungimea blocului de informații plus 4 ori numărul de culori palete ar trebui să fie egale cu decalajul de date imagine. Cu alte cuvinte14 + 40 + 4 * infoheader.ncolours = header.offset

Cod sursa

Iată sursa oferită de Michael Sweet: BITMAP.H, BITMAP.C, si BMPVIEW.C.

Și un exemplu de cod de mine, parse.c și un exemplu de 24 biți rgb fișier BMP pentru testare. Rețineți că niciunul dintre aceste segmente de cod nu se va ocupa de toate tipurile de fișiere BMP, în special, acestea nu se ocupă de fișiere comprimate BMP. Ar trebui să fie un bun punct de plecare pentru variațiile întâlnite și pentru cei care doresc să scrie fișiere compatibile BMP. Pe de altă parte, dacă aveți sau scrieți un mai bun handler BMP, atunci sunteți binevenit să vă prezinați adăugarea aici.

Contribuția lui Adam Majewski care scrie un fișier BMP de un bit pe pixel: pf1bit_bmp.c . 
Modificări la pf1bit_bmp.c de “aleksisto”: mypf1bit_bmp.c 
Contribuția lui Harold Hodgins de a repara impachetarea de octeți, necesară pentru unii compilatori: bitmap2.h .