Bitmap Windows | |
---|---|
Extensie | .bmp[1] , [1] sau [1].dib.rle |
tip MIME | imagine/bmp [2] [3] |
Dezvoltator | Microsoft [4] [5] |
Tip de format | grafică raster |
Fișiere media la Wikimedia Commons |
BMP (din engleză. B it m ap P icture ) este un format de stocare bitmap dezvoltat de Microsoft . Fișierele în format BMP pot avea extensiile .bmp , .dib și .rle .
Un număr mare de programe funcționează cu formatul BMP, deoarece suportul acestuia este integrat în sistemele de operare Windows și OS / 2 . În plus, datele în acest format sunt incluse în fișierele de resurse binare RES și în fișierele PE .
Doar rasterele cu un singur strat pot fi stocate în acest format. Fiecare pixel din fișiere diferite poate avea un număr diferit de biți (adâncime de culoare). Microsoft oferă adâncimi de biți de 1, 2, 4, 8, 16, 24, 32, 48 și 64. La adâncimi de biți de 8 și mai jos, culoarea este indicată printr-un index din tabelul de culori (paletă) și pentru mai mari. cele, printr-o valoare directă. În orice caz, o culoare poate fi specificată doar în modelul de culoare RGB (atât atunci când este specificată direct într-un pixel, cât și într-un tabel de culori), dar pe 16 și 32 de biți puteți obține un Grayscale cu o adâncime de până la 16 și 32 de biți. biți, respectiv. Transparența parțială este implementată de canalul alfa cu adâncimi de biți de la 16 biți și mai mari.
În cele mai multe cazuri, pixelii sunt stocați ca o matrice bidimensională relativ simplă. Pentru adâncimile de biți 4 și 8, este disponibilă codificarea RLE , care poate reduce dimensiunea acestora. Formatul BMP acceptă, de asemenea, încorporarea datelor JPEG și PNG . Dar cel din urmă este mai probabil să nu fie destinat stocării compacte, ci să ocolească limitările arhitecturii GDI , care nu asigură lucrul direct cu alte imagini decât formatele BMP. Cele mai recente versiuni ale formatului BMP au introdus și capabilități de gestionare a culorilor. În special, puteți să specificați puncte finale, să efectuați corecția gama și să încorporați profiluri de culoare ICC.
Când folosește formatul DIB ( Device Independent Bitmap ) , un programator poate accesa toate elementele structurilor care descriu o imagine folosind un pointer obișnuit. Dar aceste date nu sunt folosite pentru controlul direct al ecranului, deoarece sunt întotdeauna stocate în memoria sistemului, nu în memoria video dedicată . Formatul pixelului din RAM poate diferi de formatul care trebuie stocat în memoria video pentru a indica un punct de aceeași culoare. De exemplu, formatul DIB poate folosi 24 de biți pentru a specifica un pixel , iar adaptorul grafic în acel moment poate funcționa în modul HiColor cu o adâncime de culoare de 16 biți. În acest caz, un punct roșu strălucitor într-un format independent de hardware va fi specificat de trei octeți 0000FF 16 , iar în memoria video - de cuvântul F800 16 . Când copiați o imagine pe ecran, sistemul va petrece timp suplimentar transformând codurile de culoare din formatul de 24 de biți în formatul de tampon video .
Formatul DDB ( Device Dependent Bitmap ) conține întotdeauna coduri de culoare care se potrivesc cu codurile tampon video , dar poate fi stocat atât în memoria de sistem, cât și în memoria video. În ambele cazuri, conține doar coduri de culoare într-un format care va asigura că imaginea este transferată din RAM în memoria video prin simpla copiere [6] .
Informații oficiale despre formatul BMP pot fi găsite în MSDN sau în ajutorul Microsoft Windows SDK (poate fi livrat cu unele IDE-uri). Fișierul WinGDI.h de la Microsoft are toate declarațiile C++ pentru acest format. Acest articol, totuși, nu a inclus declarații de tip, deoarece acest lucru îl poate face prea greoi. În plus, unii dezvoltatori pot găsi anunțuri oficiale incomode și, prin urmare, relevanța lor este îndoielnică. Dacă aveți nevoie de numele originale ale constantelor, structurilor, tipurilor și câmpurilor acestora, atunci acestea sunt toate în textul acestui articol.
Dimensiunea maximă a celulelor indivizibile (excluzând câmpurile structurilor de biți): 32 de biți și, prin urmare, formatul poate fi clasificat ca 32 de biți. O excepție poate fi pixelii de 64 de biți, dar valorile canalului lor pot fi procesate și cu cuvinte de 16 biți. Ordinea octeților din celulele pe 16 și 32 de biți este peste tot de la scăzut la mare (little-endian). Numerele întregi sunt scrise în cod direct , cu o conectare suplimentară . În comparație cu arhitecturile hardware, ordinea octeților și formatul numărului corespund x86 .
Acest articol folosește numele de tip WinAPI ca în documentația Microsoft pentru a specifica tipuri. Pe lângă cele specifice (descrise separat în textul articolului), pot fi găsite patru tipuri numerice:
În formatul Windows Bitmap, structurile sunt înțelese ca un bloc cu celule consecutive de diferite dimensiuni fixe, care au nume condiționate (există în multe limbaje de programare), și nu ceva mai complicat (de exemplu, un flux de comandă de dimensiuni arbitrare).
Unele elemente de format au o versiune de Windows pornind de la care este acceptată. Vorbim în primul rând despre principalele biblioteci WinAPI precum gdi32.dll, shell32.dll, user32.dll și kernel32.dll. Alte componente ale sistemului de operare (de exemplu, GDI+, .NET, DirectX) pot avea alte capabilități mai avansate.
Datele în format BMP constau din trei blocuri principale de dimensiuni diferite:
Când sunt stocate într-un fișier, toate anteturile provin de la primul octet. Datele pixelilor pot fi localizate într-o poziție arbitrară din fișier (este specificat în câmpul OffBits al structurii BITMAPFILEHEADER), inclusiv la distanță de anteturi. În versiunea 5 a apărut un profil de culoare opțional și poate fi și poziționat liber, dar poziția sa este specificată de la începutul BITMAPINFO (în câmpul ProfileData).
În RAM (de exemplu, atunci când interacționați cu funcțiile GDI WinAPI), structura BITMAPFILEHEADER este exclusă din anteturi. În același timp, Microsoft recomandă plasarea profilului de culoare imediat după titluri într-un singur bloc [7] . Datele pixelilor pot avea o locație arbitrară în memorie și adresa lor este specificată în parametrii procedurii. În orice caz, se recomandă păstrarea tuturor blocurilor în memorie la adrese divizibile cu patru: există celule de 32 de biți în anteturi, iar o astfel de cerință pentru datele pixelilor este specificată în documentație [8] . Această cerință este valabilă numai pentru RAM: atunci când este stocată într-un fișier, nu este necesar să se respecte.
BITMAPFILEHEADER este o structură de 14 octeți care se află chiar la începutul fișierului. Vă rugăm să rețineți că încă de la începutul structurii, alinierea celulelor se pierde. Dacă este important pentru dvs., atunci plasați acest antet în RAM la adrese egale care nu sunt un multiplu de patru (atunci celulele pe 32 de biți vor cădea în poziții aliniate).
Poz. (hexadecimal) |
Dimensiune (octeți) |
Nume | Tipul WinAPI | Descriere |
---|---|---|---|---|
00 | 2 | bfType | CUVÂNT | Un semn pentru a distinge un format de altele (semnătură de format). Poate conține valoarea unică 4D42 16 /424D 16 (little-endian/big-endian). |
02 | patru | bfSize | DWORD | Dimensiunea fișierului în octeți. |
06 | 2 | bfRezervat1 | CUVÂNT | Rezervat și trebuie să fie zero. |
08 | 2 | bfRezervat2 | CUVÂNT | |
0A | patru | bfOffBits | DWORD | Poziția datelor pixelilor față de începutul acestei structuri (în octeți). |
Semnătura de format la vizualizarea conținutului unui fișier ca text în modul binar arată ca o pereche de caractere ASCII „BM”.
BITMAPINFO vine imediat după BITMAPFILEHEADER din fișier. Adresa acestui bloc în memorie este, de asemenea, transmisă direct unor funcții WinAPI (de exemplu, SetDIBitsToDevice sau CreateDIBitmap). În plus, același bloc este utilizat în formatele de pictograme și cursor Windows, dar acest punct nu este luat în considerare în acest articol (consultați descrierile separate ale acestor formate). Această structură este de bază și descriptivă în format BMP, așa că atunci când un nume de câmp este pur și simplu menționat, atunci este un câmp în această structură.
Blocul BITMAPINFO este format din trei părți:
Despre măștile de biți și tabelul de culori, vezi mai jos în secțiuni separate. Aici urmează descrierea structurii cu câmpuri de informații.
La momentul scrierii acestui articol, structura cu câmpuri de informații avea patru versiuni [9] : CORE, 3, 4 și 5 (denumirile versiunii sunt condiționate în acest articol pentru concizie). Pentru fiecare versiune, Microsoft a declarat patru structuri separate cu nume de câmp diferite. În acest articol, când se menționează un câmp care este prezent în mai multe structuri, partea comună tuturor structurilor este luată la sfârșitul numelui (de exemplu, BitCount în loc de bcBitCount, biBitCount, bV4BitCount sau bV5BitCount). Versiunea structurii poate fi determinată de prima celulă de 32 de biți (tip WinAPI DWORD), care conține dimensiunea sa în octeți (un întreg fără semn). Versiunea CORE se deosebește de toate prin compactitatea și utilizarea câmpurilor nesemnate exclusiv pe 16 biți. Restul de trei conțin celule identice, la care au fost adăugate altele noi în fiecare versiune nouă.
Mai jos este un tabel general al structurilor de informații:
Versiune | Dimensiune (octeți) |
Numele structurii | Versiunea Windows 9x / NT [10] | Windows CE / versiunea mobilă [11] | Note |
---|---|---|---|---|---|
CORE | 12 | BITMAPCOREHEADER | 95/NT 3.1 și mai vechi | CE 2.0/Mobile 5.0 și versiuni ulterioare | Conține numai lățimea, înălțimea și adâncimea de biți ale rasterului. |
3 | 40 | BITMAPINFHEADDER | 95/NT 3.1 și mai vechi | CE 1.0/Mobile 5.0 și versiuni ulterioare | Conține lățimea, înălțimea și adâncimea de biți a unui raster, precum și formatul pixelilor, tabelul de culori și informațiile despre rezoluție. |
patru | 108 | BITMAPV4HEADER | 95/NT 4.0 și mai vechi | nu sunt acceptate | Măști de canal selectate separat, informații adăugate despre spațiul de culoare și gama. |
5 | 124 | BITMAPV5HEADER | 98/2000 și mai vechi | nu sunt acceptate | S-a adăugat strategie de afișare a preferințelor și suport pentru profilurile ICC. |
Datorită identității câmpurilor din versiunile 3, 4 și 5, poate părea că câmpul Dimensiune poate controla numărul de câmpuri, eliminându-le pe cele neutilizate. De fapt, acest lucru nu este corect, deoarece aici dimensiunea joacă rolul versiunii (în versiunea CORE, deși câmpurile sunt și ele identice, dar de altă dimensiune și tip). Nimeni nu garantează că nu veți obține titluri mai mici sau mai mari cu un set diferit de câmpuri. Cu toate acestea, Adobe Photoshop poate salva structuri de câmpuri de informații de 52 și 56 de octeți atunci când salvează fișiere BMP. De fapt, aceasta este o versiune a patra trunchiată, care conține doar măști de biți ale canalelor (56 de octeți - versiunea cu canal alfa).
Câmpuri de informații pe 16 biți (versiunea CORE)Rețineți că aici câmpurile de lățime și înălțime conțin numere întregi fără semn, în timp ce structurile pe 32 de biți stochează valori semnate.
Poziție în fișier (hex) |
Poziția în structură (hex) |
Dimensiune (octeți) |
Nume | Tipul WinAPI | Descriere |
---|---|---|---|---|---|
0E | 00 | patru | bcSize | DWORD | Mărimea acestei structuri în octeți, indicând și versiunea structurii (ar trebui să fie 12 aici). |
12 | 04 | 2 | bcWidth | CUVÂNT | Lățimea (bcWidth) și înălțimea (bcHeight) rasterului în pixeli. Specificat ca un întreg fără semn. Valoarea 0 nu este documentată. |
paisprezece | 06 | 2 | bcÎnălțime | CUVÂNT | |
16 | 08 | 2 | bcAvioane | CUVÂNT | Singura valoare validă în BMP este 1. Acest câmp este utilizat în pictogramele și cursoarele Windows. |
optsprezece | 0A | 2 | bcBitCount | CUVÂNT | Numărul de biți pe pixel (vezi lista celor acceptați într-o secțiune separată de mai jos). |
Tabelul de mai jos oferă o prezentare generală a câmpurilor. Puteți găsi informații detaliate în secțiunile de mai jos.
Poziție în fișier (hex) |
Poziția în structură (hex) |
Dimensiune (octeți) |
Nume (versiunile 3/4/5) |
Tipul WinAPI | Descriere |
---|---|---|---|---|---|
0E | 00 | patru | biSize bV4Size bV5Size |
DWORD | Mărimea acestei structuri în octeți, indicând și versiunea structurii (vezi tabelul de versiuni de mai sus). |
12 | 04 | patru | biWidth bV4Width bV5Width |
LUNG | Lățimea rasterului în pixeli. Specificat ca un întreg cu semn. Zero și negativ nu sunt documentate. |
16 | 08 | patru | biÎnălțime bV4Înălțime bV5Înălțime |
LUNG | Un număr întreg cu semn care conține doi parametri: înălțimea rasterului în pixeli (valoarea absolută a numărului) și ordinea în care șirurile apar în matrice bidimensionale (semnul numărului). Valoarea nulă nu este documentată. |
1A | 0C | 2 | biplanuri bV4Avioane bV5Avioane |
CUVÂNT | Singura valoare validă în BMP este 1. Acest câmp este utilizat în pictogramele și cursoarele Windows. |
1C | 0E | 2 | biBitCount bV4BitCount bV5BitCount |
CUVÂNT | Numărul de biți pe pixel (vezi lista celor acceptați într -o secțiune separată de mai jos ). |
1E | zece | patru | biCompression bV4V4Compression [12] bV5Compression |
DWORD | Specifică modul în care sunt stocați pixelii (consultați secțiunea de mai jos ). |
22 | paisprezece | patru | biSizeImage bV4SizeImage bV5SizeImage |
DWORD | Dimensiunea datelor pixelilor în octeți. Poate fi setat la zero dacă stocarea este o matrice bidimensională. |
26 | optsprezece | patru | biXPelsPerMeter bV4XPelsPerMeter bV5XPelsPerMeter |
LUNG | Numărul de pixeli pe metru orizontal și vertical (consultați secțiunea „ Rezoluția imaginii ” a acestui articol). |
2A | 1C | patru | biYPelsPerMeter bV4YPelsPerMeter bV5YPelsPerMeter |
LUNG | |
2E | douăzeci | patru | biClrUsed bV4ClrUsed bV5ClrUsed |
DWORD | Dimensiunea tabelului de culori în celule. |
32 | 24 | patru | biClrImportant bV4ClrImportant bV5ClrImportant |
DWORD | Numărul de celule de la începutul tabelului de culori până la ultima utilizată (inclusiv el însuși). |
Adăugat în versiunea 4 | |||||
Poziție în fișier (hex) |
Poziția în structură (hex) |
Dimensiune (octeți) |
Nume (versiunile 4/5) |
Tipul WinAPI | Descriere |
36 | 28 | patru | bV4RedMask bV5RedMask |
DWORD | Măști de biți pentru extragerea valorilor canalului : intensitatea roșu, verde, albastru și valoarea canalului alfa. |
3A | 2C | patru | bV4GreenMask bV5GreenMask |
DWORD | |
3E | treizeci | patru | bV4BlueMask bV5BlueMask |
DWORD | |
42 | 34 | patru | bV4AlphaMask bV5AlphaMask |
DWORD | |
46 | 38 | patru | bV4CSType bV5CSType |
DWORD | Un fel de spațiu de culoare . |
4A | 3C | 36 | bV4Endpoints bV5Endpoints |
CIEXYZTRIPLE | Valoarea acestor patru câmpuri este luată în considerare numai dacă câmpul CSType conține 0 (LCS_CALIBRATED_RGB). Apoi punctele finale și valorile gamma pentru cele trei componente de culoare sunt specificate în aceste câmpuri. |
6E | 60 | patru | bV4GammaRed bV5GammaRed |
DWORD [13] | |
72 | 64 | patru | bV4GammaGreen bV5GammaGreen |
DWORD [13] | |
76 | 68 | patru | bV4GammaBlue bV5GammaBlue |
DWORD [13] | |
Adăugat în versiunea 5 | |||||
Poziție în fișier (hex) |
Poziția în structură (hex) |
Dimensiune (octeți) |
Nume | Tipul WinAPI | Descriere |
7A | 6C | patru | bV5Intenție | DWORD | Preferințe de randare raster . |
7E | 70 | patru | bV5ProfileData | DWORD | Offset-ul de octeți a profilului de culoare de la începutul BITMAPINFO (vezi și secțiunea Profil de culoare mai târziu în acest articol). |
82 | 74 | patru | bV5ProfileSize | DWORD | Dacă un profil de culoare este inclus direct în BMP, atunci dimensiunea acestuia în octeți este indicată aici. |
86 | 78 | patru | bV5 Rezervat | DWORD | Rezervat și trebuie setat la zero. |
Câmpul BitCount conține numărul de biți pe pixel. Dacă acolo este indicată o valoare diferită de zero, atunci aceasta este adâncimea reală de biți. Conținutul zero al câmpului BitCount este indicat dacă pixelii sunt stocați în format JPEG sau PNG. Apoi, adâncimea reală de biți va fi determinată de aceste formate. Biții formatului BMP pur sunt prezentați în tabelul de mai jos:
Pic | octet | BITMAPINFO | RLE | Măști de canal | Suport software | ||||
---|---|---|---|---|---|---|---|---|---|
CORE | 3, 4, 5 | Windows 9x și NT | Windows CE și Mobile | GDI+ și .NET | |||||
unu | ⅛ | da | da | Nu | Nu | da | da | da | |
2 | ¼ | da | da | Nu | Nu | Nu | da | Nu | |
patru | ½ | da | da | da | Nu | da | da | da | |
opt | unu | da | da | da | Nu | da | da | da | |
16 | 2 | Nu | da | Nu | da | da | da | da | |
24 | 3 | da | da | Nu | Nu | da | da | da | |
32 | patru | Nu | da | Nu | da | da | da | da | |
48 | 6 | Nu | da | Nu | Nu | Nu | Nu | da | |
64 | opt | Nu | da | Nu | Nu | Nu | Nu | da |
Note la tabel:
1. Coloana „BITMAPINFO” arată suport pentru adâncimea de biți numai de la Microsoft.
2. Windows CE 1.0 și 1.01 acceptă doar adâncimile de biți 1 și 2 [14] .
3. Canalele color GDI+ versiunea 1.0 pe 16 biți pot fi citite numai, transformându-le imediat la 8 biți [15] .
La adâncimi de biți de 8 și mai jos, culoarea unui pixel este indicată printr-un index în tabelul de culori, în biți mai mari: printr-o valoare directă în modelul de culoare RGB . Opțional se poate adăuga un canal alfa pe 16 și 32 de biți, iar pe 64 de biți este prezent permanent.
Tabelul arată doar bitness-ul documentat de Microsoft. Formatul în sine nu conține nicio restricție fundamentală privind utilizarea oricărui bitness care nu este menționat aici.
Fișierele BMP de 1 bit cu negru pur (bit off) și alb (bit on) sunt numite monocrom. Astfel de fișiere sunt de obicei folosite ca măști pentru alte bitmap-uri. Poate că ați întâlnit în mod constant doar astfel de rastere de 1 bit. De fapt, formatul Windows Bitmap nu impune nicio restricție asupra culorilor care vor fi folosite pentru fiecare dintre valorile biților.
De asemenea, puteți întâlni următoarele nume de biți: CGA pentru doi biți, EGA pentru patru, HiColor (HighColor) pentru 16 biți, TrueColor pentru 24 și 32 de biți cu transluciditate, DeepColor pentru biți înalți și, eventual, altele. Aceste nume datează de la dezvoltarea afișajelor bitmap color și se referă mai mult la adâncimea lor de culoare . Până în momentul în care a fost scris acest articol (2014), astfel de nume nu au fost folosite de multă vreme din cauza prevalenței puternice a dispozitivelor pe 24 de biți (în schimb, adâncimea culorii în biți sau numărul lor este pur și simplu indicată). Și fișierele BMP cu un bit mai mic sunt salvate într-o măsură mai mare nu pentru afișare pe dispozitive CGA sau EGA, ci pentru compactitate în comparație cu formatele pe 24 și 32 de biți dacă se utilizează un număr mic de culori.
Pentru fiecare grup de biți sunt utilizate valori limitate separate de compresie, dar în total valorile lor sunt unice. Microsoft a documentat următoarele valori (tabelul listează numele constantelor din această corporație):
Sens | Nume constant | Aplicabil pentru BitCount |
Stocare în pixeli | Semn de înălțime | Versiunea Windows | |
---|---|---|---|---|---|---|
9x/NT | CE | |||||
0 | BI_RGB | oricare în afară de zero | matrice bidimensională | +/− | 95/NT3.1 | CE 1.0 |
unu | BI_RLE8 | opt | Codificare RLE | + | 95/NT3.1 | (nu sub.) |
2 | BI_RLE4 | patru | Codificare RLE | + | 95/NT3.1 | (nu sub.) |
3 | BI_BITFIELDS | 16 și 32 | Matrice 2D cu măști de canale de culoare | +/− | 95/NT3.1 | CE 2.0 |
patru | BI_JPEG | 0 | în fișierul jpeg încorporat | ?/− [16] | 98/2000 | (nu sub.) |
5 | BI_PNG | 0 | în fișierul PNG încorporat | ?/− [16] | 98/2000 | (nu sub.) |
6 | BI_ALPHABITFIELDS | 16 și 32 | Matrice 2D cu măști de culoare și canal alfa | +/− | (nu sub.) | .NET 4.0 |
Tabelul de culori face parte din blocul BITMAPINFO și poate fi utilizat în două moduri:
Poziția tabelului de culori este specificată de la începutul blocului BITMAPINFO. În mod implicit, vine imediat după structura de informații (dimensiunea sa nesemnată în octeți poate fi citită din primul câmp de 32 de biți). Dar între structura cu câmpuri și tabelul de culori, măștile de biți de patru octeți pot fi folosite pentru a extrage canalele de culoare (se aplică doar pentru 16 și 32 de biți). Acestea sunt acolo doar dacă se folosește versiunea 3 a structurii de informații (Size = 40) și câmpul Compression conține 3 (BI_BITFIELDS) sau 6 (BI_ALPHABITFIELDS). Apoi 12 octeți (dacă este specificat BI_BITFIELDS) sau 16 octeți (dacă este specificat BI_ALPHABITFIELDS) [17] trebuie adăugați la dimensiunea câmpurilor de informații . Rezultă 6 opțiuni pentru locația tabelului:
Versiunea antet |
Poziție (hex) | Note | |
---|---|---|---|
În dosar | În BITMAPINFO | ||
CORE | 1A | 0C | măștile de canal nu sunt acceptate |
3 | 36 | 28 | Compresia nu conține 3 sau 6 |
42 | 34 | Compresie = 3 (BI_BITFIELDS) | |
46 | 38 | Compresie = 6 (BI_ALPHABITFIELDS) | |
patru | 7A | 6C | măștile de canal sunt încorporate în câmpurile de informații |
5 | 8A | 7B |
Numărul de celule din tabel este determinat de câmpurile BitCount și ClrUsed. Cu adâncimi de biți de 8 și mai mici, numărul maxim de celule din tabel este luat ca 2 biți : 2 într-un raster de un bit, 4 într-un raster de doi biți, 16 într-unul de 4 biți și 256 într-un raster de 8 - bit unu. În bitness-ul dat, tabelul conține întotdeauna acest număr maxim de celule dacă este folosit antetul versiunii CORE (Size = 12) sau dacă câmpul ClrUsed conține 0 în alte versiuni. În toate celelalte cazuri, indiferent de bitness, tabelul conține atâtea celule câte specificate în câmpul ClrUsed [18] .
Tabelul în sine este o matrice unidimensională care poate conține trei tipuri de celule:
Nu toate celulele pot fi utilizate în întregul tabel, iar câmpul ClrImportant conține numărul de celule de la începutul tabelului până la ultima utilizată (inclusiv el însuși). O valoare de 0 în câmpul ClrImportant indică faptul că întregul tabel este utilizat. Este mai bine să plasați celulele implicate chiar la începutul tabelului și este recomandat să le sortați în ordine descrescătoare a importanței (în cazul în care trebuie să le reduceți numărul).
Dacă imaginea are 16 sau 32 de biți, atunci pot fi specificate măști de 32 de biți pentru a extrage canalele de culoare. Acest lucru se datorează faptului că 16 nu este un multiplu al lui 3 și, prin urmare, biții pot fi alocați în moduri diferite. Pentru comoditate, imaginile pe 32 de biți folosesc canale pe 8 biți și, prin urmare, suportul pentru acestea poate părea redundant. De fapt, aici masca face posibilă activarea/dezactivarea canalului alfa sau setarea ordinii componentelor care vi se potrivește, și nu doar ajustarea rezoluției acestora. Când se aplică măști, celula de pixeli este citită în întregime ca cuvântul mașină corespunzător în little-endian.
Prezența măștilor de biți depinde de versiunea câmpurilor de informații ale structurii BITMAPINFO și de câmpul Compresie din aceasta. Pentru versiunea CORE, măștile arbitrare nu pot fi specificate, deoarece nu există câmpuri de compresie și câmpuri de mască separate. În alte versiuni, măștile de culoare sunt activate dacă Comprimarea conține 3 (BI_BITFIELDS). Masca de canal alfa este întotdeauna folosită în versiunile 4 și 5. Deoarece Windows CE nu acceptă aceste două versiuni, în care există un câmp special pentru aceasta, pentru a treia versiune a fost introdusă valoarea 6 (BI_ALPHABITFIELDS) a câmpului Compresie, care adaugă atât măști de culoare, cât și un canal alfa de mască (acceptat începând cu Windows CE .NET 4.0).
Poziția măștilor de biți este fixă indiferent de versiunea antetului: 36 h în întregul fișier sau 28 h de la începutul blocului BITMAPINFO. În versiunile 4 și 5, câmpurile concepute special pentru ei sunt situate în acest loc. În versiunea 3, măștile de biți ar trebui să fie localizate imediat după câmpurile de informații și astfel se încadrează exact în pozițiile câmpurilor corespunzătoare în versiunile mai vechi. Vă rugăm să rețineți că în cea de-a treia versiune, dacă există măști, tabelul de culori este deplasat cu 12 sau 16 octeți înainte, situat imediat după ele. Măștile de culoare de 4 octeți sunt în ordinea roșu, verde, albastru. Masca canalului alfa este deja în spatele lor.
Documentația Microsoft se aplică doar unei singure cerințe obligatorii pentru măștile de biți: fiecare mască trebuie să fie învecinată. Despre cazul intersectării măștilor, acolo se spune că este de dorit să nu se facă acest lucru [19] . Microsoft mai spune că nu este necesar să folosiți toți biții unui pixel [20] . Nu există cerințe pentru conținutul biților neutilizați.
Rețineți că nimeni nu garantează că pot fi utilizate măști mai largi de 8 biți. Și nu se spune nimic despre cazul în care orice canal va avea o mască nulă (de exemplu, când nu este cu adevărat folosit). Aici, este posibilă o situație în care toate componentele vor avea zero măști și va rămâne un canal alfa (care, în acest caz, poate ocupa toți biții). Masca zero a unui canal de culoare poate fi interpretată în două moduri: valoarea sa este luată ca zero, sau pixelii acestui canal nu sunt afectați la desen. Dacă luăm prima interpretare cu un singur canal alfa, atunci canalul alfa va seta în esență gradul de înnegrire al pixelului. Pe lângă opțiunile vagi, există și una interesantă. Deoarece intersecțiile nu sunt interzise, este posibil să setați toate canalele într-o singură poziție și, prin urmare, să obțineți o scală de gri .
Unele software au un set limitat de măști de biți acceptate. Tabelul de mai jos listează opțiunile disponibile în aceste medii limitate:
Bitness | * | Valori masca (hex) | Suport software | |||||
---|---|---|---|---|---|---|---|---|
roșu | Verde | Albastru | Alfa | Nefolosit | Windows 9x [21] | GDI+ [22] și .NET [23] | ||
16 | (A) | 7C00 | 03E0 | 001F | 0000 | 8000 | da | da |
7C00 | 03E0 | 001F | 8000 | 0000 | Nu | da | ||
F800 | 07E0 | 001F | 0000 | 0000 | da | da | ||
(b) | FFFF | FFFF | FFFF | 0000 | 0000 | Nu | da | |
32 | (A) | 00FF:0000 | 0000:FF00 | 0000:00FF | 0000:0000 | FF00:0000 | da | da |
00FF:0000 | 0000:FF00 | 0000:00FF | FF00:0000 | 0000:0000 | Nu | da |
Note de tabel:
(a) Aceste seturi sunt utilizate implicit la 16 și 32 de biți dacă nu sunt specificate măști de extracție a culorilor.
(b) Acest set de măști implementează în mod inerent scala de gri pe 16 biți.
În fișier, poziția datelor pixelilor poate fi găsită în câmpul OffBits al structurii BITMAFILEHEADER. În timpul rulării, aplicația stochează adresa datelor pixelilor acolo unde este convenabil. Documentația Microsoft menționează, de asemenea, așa-numitele bitmap -uri împachetate , care sunt indicate printr-o singură adresă a blocului BITMAPINFO. Pentru astfel de hărți de biți, datele pixelilor urmează imediat antet (inclusiv, pe lângă câmpurile de informații, măști de biți și un tabel de culori) [24] .
Mărimea datelor pixelilor în octeți este stocată în câmpul SizeImage al structurii BITMAPINFO. Este dimensiunea „brută” a acelui bloc continuu care conține date pentru formarea pixelilor (indiferent de format), și nu unul dezambalat, care este scris acolo. În mod implicit, acest câmp trebuie să conțină valoarea curentă, deoarece poate fi folosit pentru a afla exact câți octeți trebuie citiți din fișier pentru a obține pixeli. Cu toate acestea, este legal să păstrați acest câmp zero atunci când stocați pixeli ca matrice bidimensionale (când câmpul Compression conține valoarea 0 (BI_RGB), 3 (BI_BITFIELDS) sau 6 (BI_ALPHABITFIELDS) [25] ). Apoi dimensiunea pixelilor, dacă este necesar, poate fi calculată relativ rapid pe baza adâncimii de biți, lățimii și înălțimii rasterului.
Există trei moduri de a stoca pixeli în formatul Windows Bitmap (consultați și secțiunea Câmp de compresie a acestui articol):
Subsecțiunile de mai jos descriu fiecare dintre ele separat.
Specificarea culorii și valorii canalului alfaPentru a specifica o culoare atunci când este stocată în format BMP, indiferent de modul în care este specificată, sunt utilizate numai numere întregi fără semn. Culoarea pixelului în sine poate fi setată în două moduri:
Al doilea este util atunci când setul de culori este destul de mare sau imprevizibil (de exemplu, în timpul procesării imaginii). Prima metodă oferă atât un aspect compact cu un set mic de culori, cât și o oarecare comoditate în gestionarea culorilor utilizate (doar schimbați valoarea culorii în paletă). Tabelul de culori în sine este specificat fie ca indici nesemnați de 16 biți în paleta de sistem (vezi secțiunea „ Tabel de culori ” din acest articol), fie în RGB ca într-un pixel, dar exclusiv prin valorile canalului de 8 biți.
Indexul din tabelul de culori este numărul celulei din acesta de la începutul tabelului (se folosește numerotarea continuă începând de la zero). Pentru fiecare adâncime de biți, indicele maxim este limitat în mod fundamental de valoarea 2 bit depth - 1. În realitate, acesta este limitat și de numărul de elemente din tabel (detalii în secțiunea „ Tabel de culori ” a acestui articol). Microsoft nu a documentat comportamentul atunci când este specificat un index în afara tabelului, dar GDI ia negru în acest caz.
La adâncimi de biți peste 8, culoarea unui pixel este indicată direct în modelul de culoare RGB: nivelul de roșu, verde și albastru este indicat separat. Valoarea zero a oricăruia dintre canale înseamnă absența completă a nuanței corespunzătoare și maximul: prezența sa completă. Rezoluția valorilor canalului este variabilă și are propria sa în fiecare adâncime de biți (pentru valori specifice, consultați secțiunea despre stocarea pixelilor într-o matrice bidimensională a acestui articol). În același timp, la adâncimi de biți de 16 și 32, nu poate fi setată doar rezoluția arbitrară, ci și individuală pentru fiecare canal (de exemplu, 5 biți pentru roșu și albastru, dar 6 biți pentru verde). În ciuda numărului mare de opțiuni pentru setarea rezoluției valorilor, documentația Microsoft nu spune cum se modifică rezoluția unei valori. Din această cauză, diferiți producători de software pot obține rezultate diferite la modificarea adâncimii de biți.
Când setați direct culoarea unui pixel, pe lângă valorile RGB, formatul Windows Bitmap vă permite opțional și să setați valori ale canalului alfa . În ceea ce privește bitness și codificarea valorilor, este identic cu canalele de culoare: are un bitness arbitrar și se folosesc numere întregi fără semn. În ceea ce privește potrivirea valorii, zero corespunde transparenței totale, iar numărul maxim disponibil corespunde completării.
Matrice bidimensionalăPixelii de orice biți pot fi stocați într-o matrice bidimensională. Cu această metodă de stocare, câmpul Compression conține valoarea 0 (BI_RGB), 3 (BI_BITFIELDS) sau 6 (BI_ALPHABITFIELDS). Dacă se folosește antetul versiunii CORE, oricum pixelii sunt stocați doar ca o matrice bidimensională.
În acest aspect, pixelii raster sunt scriși ca dungi orizontale cu un singur pixel, pe care Microsoft le numește adesea „ scanări ” în documentația sa (în rusă, cel mai apropiat cuvânt este linii ). În memorie, aceste rânduri sunt scrise în ordine, dar cu o înălțime pozitivă: începând de la cea de jos ( în engleză de jos în sus bitmap ), și cu o înălțime negativă: de la foarte sus ( în engleză top-down bitmap ). În cadrul fiecărui rând orizontal, pixelii sunt scriși strict doar de la stânga la dreapta. Pixelii mai mici de 8 biți sunt plasați în octeți, umplând biții de la mare la mic, rezultând valorile numerice hexazecimale/binare ale pixelilor mai asemănătoare cu imaginea de ieșire. Dacă adâncimea de biți este de 16 sau 32, atunci procesarea este efectuată de cuvinte întregi de mașină de aceeași dimensiune, cu ordinea biților de la mic la mare (little-endian). Rândurile, indiferent de dimensiunea celulei, trebuie să fie completate cu zerouri până la un multiplu de patru octeți de dimensiune [8] . Din această cauză, cu o lățime a imaginii non-multiple, biți neutilizați sau octeți întregi pot apărea la sfârșitul rândurilor. Dar datorită multiplicității garantate a dimensiunii rândului, procesarea se poate face cu cuvinte mașină de 8, 16 sau 32 de biți, după cum alegeți. Și Microsoft are în continuare următoarea tendință în adâncimi de biți mai mari de 8: componenta albastră (albastru) este plasată în biții inferioare / primii octeți, verde (verde) în următorii și roșu (roșu) este mai vechi / cel mai îndepărtat, iar dacă există un canal alfa, apoi este în cei mai semnificativi biți/ultimii octeți.
Diagrama de mai jos arată aranjarea pixelilor în biți mai mici de 8 :
biți | 7 | 6 | 5 | patru | 3 | 2 | unu | 0 |
1 bit | 0 | unu | 2 | 3 | patru | 5 | 6 | 7 |
2 biți | 0 | unu | 2 | 3 | ||||
4 biți | 0 | unu |
La 16 și 32 de biți, pixelii sunt procesați de cuvinte-mașină de aceeași dimensiune (presupunând ordinea octetilor mici-endian), care aplică măști de biți de canal . Dacă nu sunt date măști de biți individuale, atunci structura va fi următoarea. La 16 biți, 5 biți sunt alocați fiecărui canal. Albastrul este în biții cei mai puțin semnificativi (masca 001F 16 ), verdele este în poziția 5 (masca 03E0 16 ), roșu: începând cu al 10-lea bit (masca 7C00 16 ), iar cel mai semnificativ bit rămas 15 nu este utilizat. Dacă sunt utilizați 32 de biți, atunci în mod implicit fiecărui canal i se atribuie un octet (8 biți). Componentele sunt aranjate similar: albastru în biții inferiori (masca 0000:00FF 16 ), verde începând cu bitul 8 (masca 0000:FF00 16 ), roșu începând cu bitul 16 (masca 00FF:0000 16 ), iar octetul înalt este nu este folosit (este folosit ca canal alfa doar dacă îl arăți direct) [26] . Deoarece ar trebui să fie citit în ordinea octet-cu-byte, dacă citiți valori din memorie octet-cu-octet, acestea vor fi în aceeași ordine (albastrul va fi primul).
Cu o adâncime de biți de 24 , fiecare canal are un octet, iar cu o adâncime de biți de 48 și 64 : un cuvânt de mașină de 16 biți. În toate cele trei cazuri, în memorie, componentele de culoare merg în ordinea: albastru, verde, roșu. În BMP-urile pe 64 de biți, culorile sunt urmate suplimentar de un canal alfa de 16 biți. Dacă doriți să procesați un pixel de 64 de biți cu un singur cuvânt de mașină, atunci în albastru little-endian va fi în cei 16 biți inferiori, iar canalul alfa va fi în cei mai mari. Verdele, respectiv, va fi lângă roșu și albastru - lângă alfa. Și puteți vedea că în 24 de biți formatul pixelilor corespunde structurii RGBTRIPLE din tabelul de culori.
Codificare RLEUtilizarea codificării RLE de către Microsoft este documentată numai pentru adâncimile de biți 4 și 8. Când este utilizat în BITMAPINFO, câmpul Compresie trebuie să conțină 2 (BI_RLE4) la adâncimea de biți 4 sau 1 (BI_RLE8) cu pixeli de opt biți. Înălțimea rasterului trebuie specificată ca număr pozitiv.
În formatul Windows Bitmap, codarea RLE poate fi comparată cu desenul cu comenzi simple. Desenul începe de la pixelul din stânga jos (ai grijă: în rastere în general, pixelul din stânga sus poate fi mai familiar) și continuă spre dreapta și sus. Pixelii din afara dimensiunii bitmap nu sunt desenați (acest lucru nu este menționat în documentație, dar GDI prezintă acest comportament). Instrucțiunile RLE vă permit să întrerupeți desenul unei linii orizontale, a întregii imagini și, de asemenea, să mutați cursorul de desen în altă poziție. Ca rezultat, este posibil ca unii pixeli să nu fie desenați. Documentația nu oferă în mod explicit culori pentru pixelii nedesenați, drept urmare interpretarea poate varia: pixelii lipsă fie rămân transparenți, fie dobândesc o culoare cu indicele 0. Dacă facem prima ipoteză, atunci putem spune că 4- și 8 Modurile -bit se datorează faptului că RLE acceptă implicit transparența, dar acest comportament nu este garantat.
Formarea imaginii în timpul codării RLE se realizează prin comenzi. Fiecare comandă trebuie să înceapă neapărat cu o adresă pară (aliniată la o limită de 16 biți). Există cinci comenzi, care sunt definite de o pereche de octeți:
Octet 1 (hex) |
Octet 2 (hex) |
Descriere |
---|---|---|
01..FF _ _ | 00..FF _ _ | Pornind de la poziția curentă și deplasându-ne spre dreapta, desenați cât mai mulți pixeli sunt specificati în primul octet. Valorile pixelilor sunt preluate din al doilea octet. În BMP-urile pe 8 biți, întregul octet este o valoare. În 4 biți, se ia pe rând cel mai înalt nibble și apoi cel mai mic nibble (patru biți). |
00 | 00 | Mutați cursorul la începutul (cel mai din stânga) al următoarei orizontale (sus). |
00 | 01 | Opriți desenul (sfârșitul atins). |
00 | 02 | Mutați cursorul la dreapta și în sus cu valorile specificate în următorii doi octeți. Primul octet următor conține valoarea pentru deplasarea orizontală, iar următorul octet conține valoarea pentru deplasarea verticală. Ambele valori: numere întregi fără semn (nu pot fi deplasate la stânga sau în jos). |
00 | 03..FF _ _ | Din poziția curentă și mai în dreapta, desenați pixelii cu valorile care vin după această pereche de octeți. Al doilea octet al comenzii conține numărul de pixeli care trebuie pictat (și anume pixeli, nu octeți). Într-un raster de 8 biți, fluxul de octeți este luat așa cum este. În 4 biți, nibble-urile sunt deja citite: cei 4 biți superiori din octet pentru primul pixel, cei 4 biți inferiori pentru următorul și așa mai departe de la octeții următori. Acest flux se poate termina cu un număr impar de octeți, iar instrucțiunile necesită alinierea pe 16 biți. Dacă se întâmplă acest lucru, atunci se adaugă un octet suplimentar (conținutul său nu contează). |
Când se ajunge la marginea dreaptă a orizontalei, nu se face nicio translație la următoarea. Prin urmare, trebuie să inserați în mod specific comanda pentru a încheia rândul. Și după cum puteți vedea din tabel, setul de comenzi nu vă permite să vă deplasați în jos sau să reveniți la orizontală. Prin urmare, puteți opri desenul dacă este atinsă marginea de sus.
Încorporarea datelor în formatele JPEG și PNGÎncepând cu Windows 98/ME și 2000/XP, funcțiile sistemului vă permit să stocați pixeli în formatele JPEG și PNG . Nu se știe nimic despre gradul de suport pentru aceste două formate de către sistem.
Pentru a încorpora un JPEG sau PNG, trebuie să resetați câmpul BitCount din BITMAPINFO și să specificați valoarea 4 (BI_JPEG) sau 5 (PI_PNG) în Compression. Valoarea câmpului SizeImage în acest caz va fi egală cu dimensiunea fișierului JPEG sau PNG care este încorporat în locul datelor pixeli așa cum sunt. Lățimea și înălțimea din antet sunt deja indicate pentru imaginea decodificată. Documentația nu spune în mod direct nimic despre semnul câmpului Înălțime pentru acest caz particular, dar se pare că este necesar să se noteze o valoare negativă [16] .
Pentru a compara pixelii fără dimensiuni cu dimensiunile materialelor, sunt utilizate câmpurile XPelsPerMeter și YPelsPerMeter. În aceste câmpuri, un număr întreg indică câți pixeli din această imagine cad pe un metru liniar, separat orizontal (XPelsPerMeter) și vertical (YPelsPerMeter). Microsoft a declarat aceste două câmpuri ca fiind un tip numeric semnat, dar documentația nu spune nimic despre valorile negative. Nici despre valoarea zero nu se spune nimic, dar este mai logic să o luăm pentru o rezoluție nedeterminată atunci când este necunoscută sau nu are valoare.
Rezoluția este adesea specificată cu referire nu la dimensiunile metrice, ci în puncte pe inch ( DPI / PPI ). Pentru translația înainte și înapoi, se ia un inch egal cu 25,4 mm (inch englez). Formule matematice pentru conversia pixelilor/inci (PPI) în pixeli/metru (PPM) și invers:
Dacă sunteți interesat de o traducere întregă exactă, atunci apar următoarele expresii:
PPM = (PPI * 5000 + 64) / 127 PPI = (PPM * 127 + 2500) / 5000După ele, rotunjirea se va face la cel mai apropiat număr întreg. Dacă doriți să rotunjiți în jos, atunci nu adăugați jumătate din divizor. Dacă vrei să crești, adaugă un divizor redus cu unu.
Mai jos sunt valorile PPM precalculate pentru unele PPI/DPI:
În câmpurile de informații, câmpul principal care specifică spațiul de culoare este câmpul CSType. Valorile sale permise sunt prezentate în tabelul de mai jos:
Sens | Versiunea BITMAPINFO [27] |
Nume constant | Descriere | |
---|---|---|---|---|
hex | Text | |||
0 | (Nu) | patru | LCS_CALIBRATED_RGB | Ajustare bazată pe valorile Endpoints, GammaRed, GammaGreen și GammaBlue. |
73524742 | „sRGB” | patru | LCS_sRGB | Este utilizat spațiul de culoare sRGB . |
57696E20 | „Câștigă” [28] | patru | LCS_WINDOWS_COLOR_SPACE | Spațiu de sistem implicit (sRGB). |
4C494E4B | 'LEGĂTURĂ' | 5 | PROFILE_LINKED | Profil de culoare într-un alt fișier. |
4D424544 | „MBED” | 5 | PROFILE_EMBEDDED | Profilul de culoare inclus în acest fișier. |
Microsoft a declarat valorile constantelor nu ca valori numerice, ci ca valori text de patru caractere [29] . În acest caz, codurile de caractere formează octeții unei valori de 32 de biți (codul ASCII al caracterului din dreapta este octetul mic, codul caracterului din stânga este octetul înalt). Când vizualizați conținutul binar al unui fișier ca text, astfel de valori codificate ASCII vor fi afișate înapoi (de exemplu, „KNIL” mai degrabă decât „LINK”).
Puncte finale și valori gammaFormatul Windows Bitmap permite corectarea culorii prin specificarea punctelor finale roșii, verzi și albastre, precum și a valorilor gamma . Pentru a face acest lucru, câmpul CSType trebuie să conțină valoarea 0 (LCS_CALIBRATED_RGB). Valorile corective sunt scrise în câmpurile Endpoints, GammaRed, GammaGreen și GammaBlue (pentru alte valori CSType, aceste patru câmpuri sunt ignorate).
Câmpul EndPoints de 36 de octeți este o structură CIEXYZTRIPLE care constă din trei câmpuri ciexyzRed (punct final roșu), ciexyzGreen (punct verde) și ciexyzBlue (albastru). Aceste trei câmpuri sunt la rândul lor și structuri CIEXYZ cu trei câmpuri ciexyzX, ciexyzY și ciexyzZ de tip FXPT2DOT30. PXPT2DOT30 este un număr fix de 32 de biți fără semn cu 2 biți înalți pentru partea întreagă și 30 de biți mici pentru partea fracțională.
Valoarea gamma este scrisă în câmpurile corespunzătoare pentru fiecare canal de culoare separat: GammaRed (roșu), GammaGreen (verde) și GammaBlue (albastru). În declarația structurilor de informații, Microsoft a specificat tipul DWORD pentru aceste câmpuri. În același timp, în fișierul WinGDI.h, există o declarație mai adecvată a tipului FXPT16DOT16 (pe baza tipului lung), care este un număr nesemnat pe 32 de biți, cu o parte fracționară în cei 16 biți inferiori și un număr întreg. parte în cele 16 superioare. De menționat că în MSDN, în paginile despre structurile BITMAPV4HEADER și BITMAPV5HEADER , asta este tot ce se spune. În articolul despre structura LOGCOLORSPACE, se spune că octetul înalt și cel mic ar trebui setat la zero în câmpuri similare (de fapt, în locul formatului 16.16 se folosește formatul 8.8, care se află la mijlocul unui 32). celula de -bit) [30] .
Mai jos sunt valorile celor patru câmpuri de mai sus în funcție de spațiul de culoare sRGB [31] :
Camp | Sens | |
---|---|---|
Fracționat | hex | |
EndPoints.ciexyzRed.ciexyzX | 0,64 | 28F5C28F |
EndPoints.ciexyzRed.ciexyzY | 0,33 | 151EB852 |
EndPoints.ciexyzRed.ciexyzZ | 0,03 | 01EB851F |
EndPoints.ciexyzGreen.ciexyzX | 0,30 | 13333333 |
EndPoints.ciexyzGreen.ciexyzY | 0,60 | 26666666 |
EndPoints.ciexyzGreen.ciexyzZ | 0,10 | 06666666 |
EndPoints.ciexyzBlue.ciexyzX | 0,15 | 0999999A |
EndPoints.ciexyzBlue.ciexyzY | 0,06 | 03D70A3D |
EndPoints.ciexyzBlue.ciexyzZ | 0,79 | 328F5C29 |
GammaRed GammaGreen GammaBlue |
2.20 | 0002199A [32] |
În fișierul BMP, dacă este necesar, un profil de culoare poate fi specificat fie prin includere directă, fie printr-o legătură către un alt fișier. Profilurile au apărut în a cincea versiune a BMP, iar până acum doar aici există câmpuri speciale pentru ele. Profilurile de culoare sunt acceptate numai în format ICC [33] [34] .
Când utilizați profiluri de culoare, trebuie mai întâi să specificați următoarele valori pentru câmpul CSType:
În orice caz, câmpul ProfileData specifică decalajul profilului în octeți de la începutul blocului BITMAPINFO. Dacă profilul este încorporat, atunci în ProfileSize trebuie să specificați dimensiunea acestuia în octeți (dacă este conectabil, atunci acest câmp ar trebui să fie setat la zero). Indiferent de variantă, Microsoft recomandă plasarea profilului în spatele datelor pixelilor atunci când sunt stocate într-un fișier și imediat după titlul [35] din RAM când interacționați cu funcțiile WinAPI .
Formatul ICC folosește predominant celule de 32 de biți sau multipli ai acestei dimensiuni de celule în antetul său [36] . Pe baza acestui lucru, dacă profilul este inclus direct în BMP, atunci este recomandat să îl stocați în RAM la o adresă care este un multiplu de patru octeți.
Când profilul este extern, în loc de conținutul său, un șir de text cu calea către fișier este plasat în BMP. Trebuie să fie în Windows 1252 codificare pe un singur octet (codificarea standard pentru limbile din Europa de Vest) și să se încheie cu un octet nul. Documentația nu spune nimic despre separatorii componentelor de cale și, prin urmare, cel mai probabil, puteți utiliza atât barele oblice din stânga „ \ ” cât și „dreapta” „/” . Calea poate fi atât relativă, cât și plină și de rețea [35] . Și din moment ce o codificare pe un singur octet este utilizată în specificarea căii, nu este necesar să aliniați acest șir în RAM.
Preferințe de randarePreferințele de randare ( intentii de randare în limba engleză ) au fost introduse de Consorțiul Internațional de Color (Consorțiul Internațional de Color) și determină prioritățile în cazul în care, la trecerea de la un subspațiu de culoare suportat de un dispozitiv ( gama engleză ), la un subspațiu al altuia, culorile sunt folosit în imagine, lipsă din țintă. Există, de asemenea, o definiție din ICC care definește preferințele de randare ca stilul de mapare a valorilor de culoare de la o descriere a imaginii la alta (original în engleză: „style of mapping color values of one image description to another” ) [37] ] . Microsoft a inclus un câmp special de intenție în format BMP, care poate lua valori complet conform specificației ICC. Prin urmare, pentru mai multe informații, vă rugăm să consultați documentația consorțiului, cea mai recentă versiune a cărei versiune poate fi descărcată de pe color.org [38] . La Microsoft, aceste preferințe sunt descrise pe scurt în articolul Intenții de redare pe MSDN.
Preferința este indicată în câmpul Intenție al blocului BITMAPINFO și este disponibilă doar cu versiunea a 5-a a câmpurilor de informații. Valorile pot fi după cum urmează:
Sens | Nume constant pentru BMP |
Numele ICC |
Numele Microsoft |
Constanta din fisierul Icm.h |
Constanta pentru DEVMODE |
---|---|---|---|---|---|
unu | LCS_GM_BUSINESS | saturare | Grafic | INTENT_SATURATION(2) | DMICM_SATURATE(1) |
2 | LCS_GM_GRAPHICS | colorimetric relativ media | dovada | INTENT_RELATIVE_COLORIMETRIC(1) | DMICM_COLORIMETRIC(3) |
patru | LCS_GM_IMAGES | perceptuale | imagine | INTENT_PERCEPTUAL(0) | DMICM_CONTRAST(2) |
opt | LCS_GM_ABS_COLORIMETRIC | ICC-colorimetric absolut (colometric relativ) |
Meci | INTENT_ABSOLUTE_COLORIMETRIC(3) | DMICM_ABS_COLORIMETRIC(4) |
Microsoft a declarat pentru această caracteristică cel puțin trei seturi de constante, care diferă prin semnificațiile lor și sunt folosite în locuri diferite [39] . Iată-le în cazul în care trebuie să le comparați rapid. Valorile constantelor prefixate cu „INTENT_” sunt exact aceleași cu cele utilizate în fișierele de profil ICC [40] . Constantele prefixate cu „DMICM_” sunt declarate în fișierul WinGDI.h pentru structura DEVMODE. Constantele „LCS_GM_” care sunt utilizate în BMP sunt declarate acolo și sunt destinate în primul rând structurii LOGCOLORSPACE. Există, de asemenea, nume pentru proprietățile imprimantei. Sunt similare cu cele din coloana „Nume Microsoft”, dar cu „Grafic” și „Imagini”.
Valoarea implicită, care este potrivită în primul rând pentru fotografii și imagini, poate fi 4 (LCS_GM_IMAGES). Ca atare, este recomandat atât de Microsoft [41] , cât și de ICC [42] .
Următorul program deschide un fișier BMP de 24 de biți într-un XWindow, adâncimea culorii trebuie să fie de 32 de biți, dar nu funcționează la o redare mai mică a culorii, deoarece complică exemplul:
/* Compilat cu linia: cc -o xtest xtest.c -I/usr/X11R6/include -L/usr/X11R6/lib -lX11 -lm */ #include <X11/Xlib.h> #include <X11/Xutil.h> #include <X11/Xatom.h> #include <X11/keysym.h> #include <stdlib.h> #include <stdio.h> #include <errno.h> #include <sys/stat.h> #include <unistd.h> #include <fcntl.h> #include <math.h> #include "bitmap.h" /* Definițiile antetului BMP aici, așa cum este descris mai devreme în acest articol (structurile trebuie să fie împachetate pe 2 octeți!) */ static XImage * CreateImageFromBuffer ( Display * , unsigned char * , int , int ); main ( int argc , char * argv []) { Display * dis ; Câștigă fereastră ; /* Fereastra noastră */ eveniment XEvent ; /* Dezvoltari */ GC gc ; /* Context grafic */ XImagine * imagine ; int n , latime , inaltime , fd , dimensiune ; unsigned char * date ; BITMAFILEHEADER bmp ; BITMAPINFOHEADER inf ; char * buf ; dacă ( arg < 2 ) { eroare ( "utilizați: fișier xtest.bmp \n " ); ieșire ( 1 ); } if (( fd = deschis ( argv [ 1 ], O_RDONLY )) == -1 ) { printf ( "Eroare la deschiderea bitmap \n " ); ieșire ( 1 ); } citiți ( fd , & bmp , sizeof ( BITMAPFILEHEADER )); citiți ( fd , & inf , sizeof ( BITMAPINFOHEADER )); lățime = inf . biWidth ; inaltime = inf . biÎnălțime ; if (( dis = XOpenDisplay ( getenv ( " DISPLAY " ))) == NULL ) { printf ( "Nu se poate conecta serverul X:%s \n " , strerror ( errno )); ieșire ( 1 ); } win = XCreateSimpleWindow ( dis , RootWindow ( dis , DefaultScreen ( dis )), 0 , 0 , lățime , înălțime , 5 , BlackPixel ( dis , DefaultScreen ( dis )), WhitePixel ( dis , DefaultScreen ( dis ))); XSetStandardProperties ( dis , win , argv [ 1 ], argv [ 0 ], None , argv , argc , NULL ); gc = DefaultGC ( dis , DefaultScreen ( dis )); /* Uneori, acest loc nu este completat în structură */ if ( inf . biSizeImage == 0 ) { /* Calculați dimensiunea */ dimensiune = latime * 3 + latime % 4 ; marime = marime * inaltime ; } altfel { dimensiune = inf . biSizeImage ; } buf = malloc ( dimensiune ); if ( buf == NULL ) { perror ( "malloc" ); ieșire ( 1 ); } printf ( "size =%d bytes alocate \n " , size ); /* Treceți la începutul imaginii în sine */ lseek ( fd , bmp . bfOffBits , SEEK_SET ); /* Citiți în buffer */ n = read ( fd , buf , size ); printf ( "size =%d bytes read \n " , n ); imagine = CreateImageFromBuffer ( dis , buf , width , height ); /* Ștergeți tamponul - nu mai avem nevoie de el */ liber ( buf ); XMapWindow ( dis , câștig ); XSelectInput ( dis , win , ExposureMask | KeyPressMask ); în timp ce ( 1 ) { XNextEvent ( dis , & eveniment ); if ( eveniment . xany . fereastră == câștig ) { comutare ( eveniment . tip ) { caz Expune : XPutImage ( dis , win , gc , imagine , 0 , 0 , 0 , 0 , imagine -> width , image -> height ); rupe ; case KeyPress : if ( XLookupKeysym ( & eveniment . xkey , 0 ) == XK_q ) { XDestroyImage ( imagine ); XCloseDisplay ( afișare ); close ( fd ); ieșire ( EXIT_SUCCESS ); } rupe ; implicit : rupe ; } } } } /* Creează o imagine X dintr-un fișier BMP, deoarece imaginea BMP este stocată invers * și bucla în oglindă remediază acest lucru */ XImage * CreateImageFromBuffer ( Afișare * dis , unsigned char * buf , int width , int height ) { int adâncime , ecran ; XImagine * img = NULL ; int i , j ; int numBmpBytes ; size_t numImgBytes ; int32_t * imgBuf ; int ind = 0 ; linie int ; int temp ; int ih , iw ; /* Numerele rândurilor și coloanelor pentru a reflecta */ int new_ind ; /* Index nou */ ecran = DefaultScreen ( dis ); depth = DefaultDepth ( dis , ecran ); temp = latime * 3 ; linie = temp + lățime % 4 ; /* Lungimea șirului inclusiv alinierea */ numImgBytes = ( 4 * ( latime * inaltime )); imgBuf = malloc ( numImgBytes ); /* Dimensiunea alocată pentru BMP în fișier, inclusiv alinierea */ numBmpBytes = linie * înălțime ; pentru ( i = 0 ; i < numBmpBytes ; i ++ ) { unsigned int r , g , b ; /* Omite umplutura */ dacă ( i >= temp && ( i % linie ) >= temp ) continua ; b = buf [ i ]; i ++ ; g = buf [ i ]; i ++ ; r = buf [ i ]; /* Calculați un nou indice pentru a reflecta vertical */ iw = ind % lățime ; ih = ind / lățime ; new_ind = iw + ( înălțime - ih - 1 ) * lățime ; imgBuf [ new_ind ] = ( r | g << 8 | b << 16 ) << 8 ; ind ++ ; } img = XCreateImage ( dis , CopyFromParent , adâncime , ZPixmap , 0 , ( char * ) imgBuf , lățime , înălțime , 32 , 0 ); XInitImage ( img ); /* Ordinea biților și octeților de pe computer ar trebui să fie așa */ img -> byte_order = MSBFirst ; img -> bitmap_bit_order = MSBFirst ; intoarce img ; }Microsoft Windows SDK este un kit pentru dezvoltatori care include ajutor, iar C++ include fișiere. Pe tema acestui articol, sunt relevante fișierele WinGDI.h și Icm.h, din care au fost luate în primul rând valorile constantelor. Cea mai recentă versiune a acestui kit poate fi descărcată gratuit de pe site-ul Microsoft (versiunile 6.0 și 7.1 au fost folosite în acest articol).
Microsoft nu are documentație specifică separată special pentru formatul BMP. Dar structurile sale și alte elemente sunt descrise în cadrul subsistemului GDI. Această descriere se află în ajutorul care este inclus cu SDK-ul de mai sus și, de asemenea, pe MSDN . Mai mult, în acesta din urmă este prezent pentru diferite platforme și independent în ajutorul Visual Studio. În majoritatea cazurilor, informațiile sunt identice, dar în unele locuri pot exista ceva mai multe fapte (de exemplu, ajutorul SDK-ului are mai multe informații despre suportul Windows).
Pentru informații de bază, consultați ajutorul GDI pentru platformele Windows 9x și NT. Link-uri către pagini din această secțiune care se referă doar la format și nu la funcțiile WinAPI pentru lucrul cu acesta:
Platformele Windows Compact 2013 (CE 6.0) și Mobile 6.5 au doar descrieri pentru trei structuri, dar pentru aceste platforme:
Link-uri către alte pagini din MSDN legate de formatul BMP:
Specificația de gestionare a culorilor ICC oferă informații despre profilurile de culoare (inclusiv formatul de fișier ICC), precum și despre preferințele de randare. Această specificație poate fi descărcată de pe site-ul oficial al consorțiului color.org . La momentul redactării, cea mai recentă versiune este 4.3 (decembrie 2010). Link-uri directe către PDF de pe site-ul ICC:
containere media | |
---|---|
Video/Audio | |
Audio | |
Muzică | |
Raster | |
Vector | |
Complex |