structura de format
format bmp (de la cuvintele Bitmap - bitmap, sau, vorbind în limba rusă, bitmap) este un non-comprimat (în principal), o imagine care este destul de ușor de citit și afișat în Microsoft Windows, care are o funcție specială API, care în acest de ajutor.
Pentru a începe cu vom da o reprezentare grafică a datelor în bmp (imagine preluată din MSDN).
La început se află antetul fișierului (BITMAPFILEHEADER). Este descrisă după cum urmează:
typedef struct tagBITMAPFILEHEADER
# 123;
WORD bfType;
DWORD bfSize;
WORD bfReserved1;
WORD bfReserved2;
bfOffBits DWORD;
# 125; BITMAPFILEHEADER, * PBITMAPFILEHEADER;
SetFilePointer # 40; hFile, BFH. bfOffBits. NULL. FILE_BEGIN # 41; ;
Aici și mai jos, vom presupune că variabila este declarată ca BFH BFH BITMAPFILEHEADER;
Și apoi vine structura BitmapInfoHeader, care este declarată după cum urmează:
typedef struct tagBITMAPINFOHEADER
# 123;
DWORD biSize;
LONG biWidth;
biHeight LONG;
biplanes WORD;
WORD biBitCount;
DWORD biCompression;
DWORD biSizeImage;
biXPelsPerMeter LONG;
biYPelsPerMeter LONG;
DWORD biClrUsed;
DWORD biClrImportant;
# 125; BitmapInfoHeader, * PBITMAPINFOHEADER;
biSize - este dimensiunea structurii. Acesta trebuie să fie inițializată după cum urmează: bih.biSize = sizeof (BitmapInfoHeader);
Aici din nou, și vom continua să presupunem că BIH este declarată după cum urmează: bih BitmapInfoHeader;
biWidth biHeight și specificați lățimea și înălțimea în pixeli.
biplanes specifică numărul de avioane. Deși este întotdeauna setat la 1.
biBitCount - Numărul de biți per pixel. Cititi mai multe despre discutat mai jos.
biCompression indică tipul de compresie. Nu fi surprins și nu vă fie teamă că comprimarea bruscă și bmp. Eu personal nu am văzut nici un bmp comprimat (dar nu spun că acestea nu există). Dacă nu există nici o compresie, acest indicator ar trebui să fie instalat în BI_RGB. În acest articol este vorba despre un format necomprimat, astfel încât alte steaguri eu nu sunt chiar de gând să listă. Se pare că aceeași structură este utilizată în fișierele JPEG și PNG, pentru că începând cu Windows 98, au existat opțiuni BI_JPEG, ceea ce arată că această imagine - JPEG și BI_PNG, este PNG (despre format jpeg, nu știu, eu tocmai am făcut aceste constatări, pe baza a ceea ce este scris în MSDN).
biSizeImage denotă dimensiunea imaginii în octeți. Dacă imaginea este necomprimat (adică câmpul anterior este setat la BI_RGB), trebuie să fie scrise la zero. biXPelsPerMeter și biYPelsPerMeter sunt, respectiv, rezoluția orizontală și verticală (în pixeli per metru) ale dispozitivului de capăt să fie afișat pe un bitmap (raster). Aplicația poate utiliza această valoare pentru a fi selectate din grupul bitmap resursa cea mai potrivită pentru dispozitivul dorit. Faptul că formatul bmp - este în esență un bitmap dispozitiv independent, adică, atunci când apariția a ceea ce este produs nu depinde de ceea ce raster proiectat (ca să spunem așa). De exemplu, imaginea va arata la fel, indiferent dacă acesta este desenată pe ecran sau imprimate pe o imprimantă. Dar aici este rezoluția la dispozitive diferite, și tocmai pentru a selecta imaginea cea mai potrivită din prezent și de a folosi aceste setări.
biClrUsed determină numărul de culori utilizate în tabel. Dacă această valoare este zero, apoi un raster de cel mai mare număr posibil de culori care sunt permise valoarea biBitCount. Acest lucru este valabil numai pentru imaginile comprimate. În cazul în care nu biClrUsed zero și biBitCount mai puțin de 16, atunci biClrUsed determină numărul actual de culori a motorului grafic sau driverul de dispozitiv disponibile. Dacă biBitCount mai mare sau egal cu 16, atunci biClrUsed determină mărimea tabelului de culori folosite pentru a optimiza paleta curentă a sistemului.
biClrImportant - este numărul de culori importante. Specifică numărul de culori care sunt necesare pentru a portretiza imaginea. Dacă această valoare este 0 (așa cum este cazul de obicei), atunci toate culorile sunt considerate importante.
Tipuri de format BMP
Toate tipurile de format bmp pot fi împărțite în două tipuri: palet si bespalitrovye. Acesta este utilizat în această paletă pentru a formata sau nu. Rețineți că paleta poate fi chiar formate bespalitrovyh, dar acesta nu este utilizat. În bespalitrovyh culoare bmp se calculează direct din biții care sunt în fișierul, dintr-un anumit punct. Și în fiecare paletă octet descrie unul sau mai mulți pixeli, valorile de bytes (sau biți) - un indice de paletă de culori. Pentru a începe cu un tabel care compară opțiunile posibile. Tipul de imagine (sau bespalitrovaya paleta) depinde de numărul de biți per pixel este dată, adică valoarea structurii biBitCount BitmapInfoHeader.
Palet sau format bespalitrovy
exemple de programe
Buna ziua 1. Crearea de imagini în format bmp.
Acest lucru creează o imagine monocromă. In exemplele de trei funcții: creație bmp 8, 16 și 24 de biți. Voi da doar pentru 16 biți.
// Crearea unei imagini în format bmp 16-biți, cum ar fi 5-5-5, care este un simplu o culoare
CreateBmp555 nule # 40; char * fname, culoare WORD # 41;
# 123;
HANDLE hFile;
DWORD RW;
int i, j;
// declararea structurii dorite
BFH BITMAPFILEHEADER;
bih BitmapInfoHeader;
BYTE Paletă # 91; 1024 # 93; ; // palet
// Să aibă o dimensiune a imaginii de 35 x 50 pixeli
int Lățime = 35;
int înălțime = 50;
memset # 40; Palet, 0. 1024 # 41; ; // paleta le umple cu zerouri
memset # 40; BFH, 0. sizeof # 40; BFH # 41; # 41; ;
BFH. bfType = 0x4D42; // denotă că acest bmp „BM“
BFH. bfOffBits = sizeof # 40; BFH # 41; + sizeof # 40; bih # 41; + 1,024; // Paletă ia 1Kb, dar nu-l vom folosi
BFH. bfSize = BFH. bfOffBits +
sizeof # 40; culoare # 41; * Latime * inaltime +
Inaltime * # 40; # 40; sizeof # 40; culoare # 41; * Lățime # 41; % 4 # 41; ; // Se calculează dimensiunea fișierului finală
memset # 40; bih, 0. sizeof # 40; bih # 41; # 41; ;
bih. biSize = sizeof # 40; bih # 41; ; // Deci, a pus
bih. biBitCount = 16; // 16 bpp
bih. biClrUsed = 32768; // Noi folosim 5-5-5
bih. biCompression = BI_RGB; // Fără compresie
bih. biHeight = înălțime;
bih. biWidth = Lățime;
bih. biplane = 1; // Ar trebui să fie 1
// Restul terenului rămâne 0
hFile = CreateFile # 40; fname, GENERIC_WRITE, 0. NULL. CREATE_ALWAYS, 0. NULL # 41; ;
dacă # 40; hFile == INVALID_HANDLE_VALUE # 41;
return;
// Scrie titluri
WriteFile # 40; hFile, BFH, sizeof # 40; BFH # 41;. RW, NULL # 41; ;
WriteFile # 40; hFile, bih, sizeof # 40; bih # 41;. RW, NULL # 41; ;
// paleta de scriere
WriteFile # 40; hFile, palet, 1024. RW, NULL # 41; ;
pentru # 40; i = 0; eu
pentru # 40; j = 0; j
WriteFile # 40; hFile, culoare, sizeof # 40; culoare # 41;. RW, NULL # 41; ;
# 125;
// Alinierea de frontieră
WriteFile # 40; hFile, Palette, # 40; sizeof # 40; culoare # 41; * Lățime # 41; 4%. RW, NULL # 41; ;
# 125;
CloseHandle # 40; hFile # 41; ;
# 125;
Exemplul 2. Conversia imaginilor din formatul de 8 biți (256 culori) în 24 de biți.
BOOL Convert256To24 # 40; char * fin, char * Fout # 41;
# 123;
BFH BITMAPFILEHEADER;
bih BitmapInfoHeader;
int Lățime, Înălțime;
RGBQUAD Paletă # 91; 256 # 93; ;
BYTE * inBuf;
RGBTRIPLE * outBuf;
MÂNER hin, Hout;
DWORD RW;
OffBits DWORD;
int i, j;
hin = CreateFile # 40; fin, GENERIC_READ, FILE_SHARE_READ, NULL. OPEN_EXISTING, 0. NULL # 41; ;
dacă # 40; hin == INVALID_HANDLE_VALUE # 41;
return false;
Hout = CreateFile # 40; Fout, GENERIC_WRITE, 0. NULL. CREATE_ALWAYS, 0. NULL # 41; ;
dacă # 40; Hout == INVALID_HANDLE_VALUE # 41;
# 123;
CloseHandle # 40; hin # 41; ;
return false;
# 125;
// citeste aceste
readfile # 40; hin, BFH, sizeof # 40; BFH # 41;. RW, NULL # 41; ;
readfile # 40; hin, bih, sizeof # 40; bih # 41;. RW, NULL # 41; ;
readfile # 40; hin, Palette, 256 * sizeof # 40; RGBQUAD # 41;. RW, NULL # 41; ;
// Setați indicatorul la începutul rastrului
SetFilePointer # 40; hin, BFH. bfOffBits. NULL. FILE_BEGIN # 41; ;
Lățime = bih. biWidth;
Height = bih. biHeight;
OffBits = BFH. bfOffBits;
// aloca memorie
inBuf = new BYTE # 91; lățime # 93; ;
outBuf = new RGBTRIPLE # 91; lățime # 93; ;
// Umple titlurile
BFH. bfOffBits = sizeof # 40; BFH # 41; + sizeof # 40; bih # 41; ; // nu vom scrie paleta
bih. biBitCount = 24;
BFH. bfSize = BFH. bfOffBits + 4 * latime * inaltime + Inaltime * # 40; Lățime% 4 # 41; ; // Dimensiune fișier
// Restul este neschimbat
// Scrie titluri
WriteFile # 40; Hout, BFH, sizeof # 40; BFH # 41;. RW, NULL # 41; ;
WriteFile # 40; Hout, bih, sizeof # 40; bih # 41;. RW, NULL # 41; ;
// Să începem să convertiți
pentru # 40; i = 0; eu
readfile # 40; hin, inBuf, Latime, RW, NULL # 41; ;
pentru # 40; j = 0; j
outBuf # 91; j # 93;. rgbtRed = Paletă # 91; inBuf # 91; j # 93; # 93;. rgbRed;
outBuf # 91; j # 93;. rgbtGreen = Paletă # 91; inBuf # 91; j # 93; # 93;. rgbGreen;
outBuf # 91; j # 93;. rgbtBlue = Paletă # 91; inBuf # 91; j # 93; # 93;. rgbBlue;
# 125;
WriteFile # 40; Hout, outBuf, sizeof # 40; RGBTRIPLE # 41; * Lățime, RW, NULL # 41; ;
// Scrieți coșul de gunoi pentru a alinia
WriteFile # 40; Hout, Paletă, Width% 4. RW, NULL # 41; ;
SetFilePointer # 40; hin, # 40; 3 * Lățime # 41; % 4. NULL. FILE_CURRENT # 41; ;
# 125;
șterge inBuf;
șterge outBuf;
CloseHandle # 40; hin # 41; ;
CloseHandle # 40; Hout # 41; ;
return true;
# 125;
Funcția trebuie să fie trecut numele fișierelor sursă și destinație, respectiv.