Čo znamená bmp. Aká je prípona súboru BMP? Čo je BMP

  • 08.03.2020

Skontrolovali sme malý program, ktorý pohybuje spritom po obrazovke, ale, žiaľ, nevyzeral tak, ako by sme chceli. V tomto článku sa pokúsime „urobiť poriadok“ v sprite.

Dostali sme obrázok sprite zo súboru Bmp, z tých istých súborov si môžete vziať obrázok na pozadí, kurzor myši a prvky rozhrania. Na obrazovke však nevidíme úplne to, čo sme očakávali: obraz sa ukázal byť prevrátený a navyše s inými farbami, ako je požadované. Poďme sa teda naučiť, ako správne čítať súbory Bmp a obrátiť obrázok hore nohami.

Podľa rozhodnutia vývojárov nie je formát súboru Bmp viazaný na konkrétnu hardvérovú platformu. Tento súbor má štyri časti: hlavičku, informačnú hlavičku, tabuľku farieb (paleta) a obrazové údaje. Ak súbor obsahuje obrázok s farebnou hĺbkou 24 bitov (16 miliónov farieb), potom tabuľka farieb môže chýbať, ale v našom prípade s 256 farbami áno. Je uvedená štruktúra každej časti súboru, v ktorej je uložený 256-farebný obrázok, a príslušné typy záznamov sú uvedené v.

Hlavička súboru začína na podpisov„BM“, za ktorým nasleduje dĺžka súboru v bajtoch. Ďalšie 4 bajty sú vyhradené pre ďalšie rozšírenia formátu a táto hlavička končí posunutie od začiatku súboru po zaznamenané obrazové údaje. Pri 256 farbách je tento posun 1078 – presne toľko sme museli preskočiť v našom poslednom programe, aby sme sa dostali k údajom.

Informačná hlavička začína vlastnou dĺžkou (môže sa meniť, ale pre 256-farebný súbor je to 40 bajtov) a obsahuje rozmery obrázka, rozlíšenie, charakteristiku zobrazenia farieb a ďalšie parametre.

Šírka a výška obrázka sú nastavené v bodoch rastra a možno nevyžadujú vysvetlenia.

Počet lietadiel možno použiť v súboroch s malou hĺbkou farieb. Ak je počet farieb 256 alebo viac, vždy sa rovná 1, takže toto pole už možno považovať za zastarané, ale kvôli kompatibilite je zachované.

Farebná hĺbka Považuje sa za najdôležitejšiu charakteristiku toho, ako je farba reprezentovaná v súbore a meria sa v bitoch na bod. V tomto prípade je to 8.

Kompresia. Zvyčajne sa nepoužíva v súboroch BMP, ale existuje pre to pole hlavičky. Zvyčajne je to 0, čo znamená, že obrázok nie je komprimovaný. V budúcnosti budeme používať iba takéto súbory.

Veľkosť obrazu- počet bajtov pamäte potrebnej na uloženie tohto obrázku, bez údajov palety.

Horizontálne a vertikálne rozlíšenie merané v rastrových bodoch na meter. Sú dôležité najmä pre zachovanie mierky skenovaných obrázkov. Obrázky vytvorené pomocou grafických editorov majú v týchto poliach spravidla nuly.

Počet farieb umožňuje zmenšiť veľkosť tabuľky palety, ak obrázok v skutočnosti obsahuje menej farieb, ako umožňuje zvolená farebná hĺbka. V praxi sa však s takýmito súbormi takmer nikdy nestretnete. Ak je počet farieb maximálny povolený hĺbkou farieb, napríklad 256 farieb pri 8 bitoch, pole sa nastaví na nulu.

Počet základných farieb- ide od začiatku palety a je žiaduce zobraziť ju bez skreslenia. Toto pole je dôležité, keď maximálny počet farieb zobrazenia bol menší ako paleta v súbore BMP. Pri vývoji formátu sa zjavne predpokladalo, že najčastejšie farby budú umiestnené na začiatku tabuľky. Teraz sa táto požiadavka prakticky nedodržiava, to znamená, že farby nie sú zoradené podľa frekvencie, s akou sa vyskytujú v súbore. Je to veľmi dôležité, pretože palety dvoch rôznych súborov, aj keď zložených z rovnakých farieb, by ich (farby) obsahovali v inom poradí, čo by mohlo výrazne skomplikovať súčasné zobrazovanie takýchto obrázkov na obrazovke.

Za informačnou hlavičkou nasleduje tabuľka farieb, čo je pole 256 (podľa počtu farieb) 4-bajtových polí. Každé pole zodpovedá svojej vlastnej farbe v palete a tri zo štyroch bajtov zodpovedajú zložkám modrej, zelenej a červenej zložky pre túto farbu. Posledný najvýznamnejší bajt každého poľa je rezervovaný a rovná sa 0.

Za tabuľkou farieb sú obrazové údaje, ktoré sú zapísané zdola nahor pozdĺž čiar rastra a vo vnútri čiary zľava doprava. Keďže na niektorých platformách nie je možné prečítať dátovú jednotku, ktorá je menšia ako 4 bajty, dĺžka každého riadku je zarovnaná na 4-bajtovú hranicu, to znamená, že ak dĺžka riadku nie je násobkom štyroch, je vyplnené nulami. Túto okolnosť je potrebné vziať do úvahy pri čítaní súboru, aj keď môže byť lepšie vopred dbať na to, aby vodorovné rozmery všetkých obrázkov boli násobky 4.

Ako sme už povedali, formát súboru bol navrhnutý tak, aby bol univerzálny pre rôzne platformy, a tak neprekvapí, že farby palety sú v ňom uložené iným spôsobom, ako je bežné pri VGA. Počas vykonávania postupu čítania sa vykoná potrebné prekódovanie. (O tom, čo je paleta VGA a ako s ňou pracovať, si povieme v nasledujúcich článkoch.)

Čítačka súborov BMP s 256 farbami má iba dve rutiny. Ako môžete vidieť z výpisu, rozmery obrázka musia byť odovzdané procedúre čítania súboru ReadBMP. To je výhodné, ak je potrebné obrázok prečítať neúplne. Keď sú veľkosti známe vopred, nespôsobuje to problémy, ale bolo by pekné, keby pomocou nášho modulu bolo možné prečítať akékoľvek obrázky, vrátane tých, ktorých veľkosť je vopred neznáma. Na tento účel je k dispozícii procedúra ReadBMPheader, ktorá číta iba hlavičku súboru. Jeho volaním si môžete skontrolovať, či je obrázok zaznamenaný vo vybranom 256-farebnom formáte, zistiť jeho rozmery a až potom mu prideliť pamäť a umiestniť ho do pridelenej vyrovnávacej pamäte.

Teraz pripojíme nový modul k nášmu programu. Aby sme to dosiahli, zapíšeme si jej názov do smernice o použití a tiež poskytneme pole na ukladanie údajov o palete, ktoré možno opísať takto:

P: pole bajtov;

Procedúra CreateSprite, ktorá volá operáciu na čítanie súboru z nového modulu, bola zjednodušená (pozri).

Štruktúra súboru Bmp

názov Dĺžka Zaujatosť Popis
Hlavička súboru (BitMapFileHeader)
Typ2 0 podpis "BM"
Veľkosť4 2 veľkosť súboru
Rezervované 12 6 Rezervované
Rezervované 22 8 Rezervované
OffsetBits4 10 Odsadenie obrazu od začiatku súboru
Informačná hlavička (BitMapInfoHeader)
Veľkosť4 14 Dĺžka hlavičky
šírka4 18 Šírka obrázka, body
Výška4 22 Výška obrázka, body
Lietadlá2 26 Počet lietadiel
BitCount2 28 Farebná hĺbka, počet bitov na bod
Kompresia4 30 Typ kompresie (0 – nekomprimovaný obrázok)
Veľkosť obrázka4 34 Veľkosť obrázka, bajty
XpelsPerMeter4 38 Horizontálne rozlíšenie, počet bodov na meter
YpelsPerMeter4 42 Vertikálne rozlíšenie, počet bodov na meter
Použité farby4 46 Počet použitých farieb (0 je maximum možné pre danú farebnú hĺbku)
Farby Dôležité4 50 Počet základných farieb
ColorTable
ColorTable1024 54 256 prvkov po 4 bajty
Údaje obrázka (bitové pole)
ObrázokVeľkosť1078 Obraz zaznamenaný po riadkoch zľava doprava a zdola nahor

Výpis 1

jednotka bmpread; (postupy pre prácu s Bmp) typ rozhrania arttype = arrayof byte; arptr = ^ arttype; bmFileHeader = záznam (hlavička súboru) Typf: word; (podpis) Veľkosť: longint; (dĺžka súboru v bajtoch) Res1: slovo; (vyhradené) Res2: slovo; (vyhradené) OfBm: longint; (posun obrazu v bajtoch (1078)) end; bmInfoHeader = záznam (hlavička informácií) Veľkosť: longint; (dĺžka hlavičky v bajtoch (40)) Widt: longint; (šírka obrázka (v bodoch)) Výška: longint; (výška obrázka (v bodoch)) Plán: slovo; (počet rovín (1)) BitC: slovo; (farebná hĺbka (bity na bod) (8)) Comp: longint; (typ kompresie (0 - nie)) SizI: longint; (veľkosť obrázka v bajtoch) XppM: longint; (horizontálne rozlíšenie) ((bodov na meter – zvyčajne 0)) YppM: longint; (vertikálne rozlíšenie) ((bodov na meter – zvyčajne 0)) NCoL: longint; (počet farieb) ((ak je povolené maximum 0)) NCoI: longint; (počet základných farieb) koniec; bmHeader = záznam (úplná hlavička súboru) f: bmFileHeader; (hlavička súboru) i: bmInfoHeader; (informačná hlavička) p: arrayof byte; (tabuľka palety) koniec; bmhptr = ^ bmHeader; (čítať obrázok zo súboru Bmp) procedure ReadBMP (obrázok: arptr; (pole s obrázkom) xim, yim: word; (rozmery) pal: arptr; (paleta) názov_súboru: reťazec); (názov súboru) (prečítajte si hlavičku súboru Bmp) procedure ReadBMPheader (hlavička: bmhptr; názov súboru: reťazec); implementácia ($ R-) (prečítanie obrázku zo súboru Bmp) postup ReadBMP (obrázok: arptr; xim, yim: slovo; pal: arptr; názov súboru: reťazec); var h: bmHeader; i: celé číslo; bmpfile: súbor; s: longint; začať priraďovať (bmpfile, názov súboru); reset (bmpfile, 1); blockread (bmpfile, h, sizeof (h)); (čítaj hlavičku) pre i: = 0 až yim-1 do begin (čítaj riadok po riadku) blockread (bmpfile, obrázok ^ [(yim-i-1) * xim], xim); if (xim mod 4)<>0 potom blockread (bmpfile, s, 4 - (xim mod 4)); koniec; zavrieť (bmpfile); pre i ^ = 0 až 255 do begin (konverzia palety) pal ^: = h.p shr 2; (modrá) pal ^: = h.p shr 2; (zelená) pal ^: = h.p shr 2; (červený) koniec; koniec; (prečítajte si hlavičku súboru Bmp) procedure ReadBMPheader (hlavička: bmhptr; názov súboru: reťazec); var bmpfile: súbor; začať priraďovať (bmpfile, názov súboru); reset (bmpfile, 1); blockread (bmpfile, hlavička ^, sizeof (hlavička ^)); zavrieť (bmpfile); koniec; koniec.

Výpis 2

(sprite) procedure CreateSprite (s: string; x, y, dx, dy: integer); var f: súbor; (súbor obrázka sprite) begin getmem (Sprt.Img, sizeof (SpriteArrayType)); (pridelenie pamäte pre sprite) getmem (Sprt.Back, sizeof (SpriteArrayType)); (pridelenie pamäte pre vyrovnávaciu pamäť) Readbmp (@ (Sprt.Img ^), Xsize, Ysize, @ p, s); Sprt.x: = x; Sprt.y: = y; (nastav počiatočné hodnoty) Sprt.dx: = dx; (súradnice a prírastky) Sprt.dy: = dy; koniec;

Formát súboru bmp je bitmapový a je veľmi populárny. Dobre mu „rozumie“ každý operačný systém Windows.

Otvorenie súboru s príponou bmp na počítači by malo byť automatické – stačí naň dvakrát kliknúť ľavým tlačidlom myši.

Ak sa vám to nestane, s najväčšou pravdepodobnosťou je priradenie súboru porušené, potom systém musí manuálne uviesť, ako ho otvoriť.

Ak to chcete urobiť, kliknite pravým tlačidlom myši na svoj súbor bmp, presuňte kurzor na riadok „otvoriť pomocou“ a vyberte ľubovoľný program (ak je nainštalovaný), napríklad farbu.

Aký program otvoriť rozšírenie bmp

Najjednoduchší spôsob, ako otvoriť formát bmp, je program Windows Photo Album. Nemusíte si ho sťahovať – je dodávaný s operačným systémom, to znamená, že by ho mal mať každý.

Druhým programom je „farba“. Nemusíte ho ani sťahovať - ​​je štandardne zabudovaný vo Windowse, navyše s ním môžete príponu bmp nielen upravovať, ale po otvorení uložiť v inom formáte, napríklad jpg - pre prezeranie na telefón.

Tretím programom je „PhotoScape“. Budete si ho musieť stiahnuť. Je zadarmo, v ruštine a s jeho pomocou môžete okrem prezerania spracovávať obrázky bmp.

Štvrtou aplikáciou je Paint.NET. Má tiež bezplatné ruské rozhranie, pohodlné a veľmi jednoduché na používanie, s mnohými nástrojmi na opravu a úpravu obrázkov a fotografií - je to ako náhrada za štandardný "Paint"

Piaty program "GIMP". Je to prirovnané k photoshopu. Toto je bezplatný grafický editor pre profesionálne použitie so všetkými potrebnými funkciami a je jednoduchý.

Vyššie uvedené programy, ktoré otvárajú súbory v tomto formáte, nie sú ani zďaleka všetky. Sú ich desiatky, no bežnému používateľovi počítača úplne stačia. Veľa štastia.

Tento článok je o tom, ako vyzerá grafický formát bmp. Hoci ide o jeden z jednoduchších formátov, vzhľadom na to, že existuje veľa variácií tohto formátu, nie všetky body sú zrejmé. Takže prestaňte liať vodu, začnime.

Formátovať štruktúry

Formát bmp (zo slov BitMaP - bitmapa alebo v ruštine bitmapa) je nekomprimovaný (väčšinou) obrázok, ktorý sa dá celkom ľahko čítať a vydávať v operačnom systéme Windows, ktorý má špeciálne funkcie API, ktoré pomáhajú.

Najprv si dajme grafické znázornenie údajov v bmp (obrázok prevzatý z MSDN).

Na začiatku je hlavička súboru (BITMAPFILEHEADER). Opisuje sa takto:

bfType určuje typ súboru. Tu by mal byť BM. Ak otvoríte akýkoľvek súbor BMP v texte (alebo lepšie v hex editore), uvidíte, že prvé dva znaky sú BM (zo slova BitMap, ako ste už pravdepodobne uhádli).
bfSize je veľkosť samotného súboru v bajtoch. Presne povedané, mali by ste to vypočítať (čo sa odporúča), ale nesprávne som nastavil veľkosť súboru (aj keď nie zámerne :)) a neboli žiadne problémy (ACDSee si to prečítajte bez problémov, môj program fungoval), ale neodporúčam že to píšeš schválne zle , zrazu sa objaví svedomitý program, ktorý túto veľkosť skontroluje s reálnou a rozhodne, že toto nie je bmp, ale niečo iné. V ideálnom prípade by všetky programy, aby ste sa uistili, že sú skutočne bmp, a nie falošné, mali po prvé skontrolovať, či bfType obsahuje „BM“ (bez úvodzoviek), a po druhé, či sa bfSize rovná veľkosti súboru . ..
bfReserved1 a bfReserved2 sú rezervované a musia byť nuly.
bfOffBits... Toto je jedna z najdôležitejších oblastí v tejto štruktúre. Ukazuje, kde začína samotná bitmapa vzhľadom na začiatok súboru (alebo, ako sa píše v MSDN, "od začiatku štruktúry BITMAPFILEHEADER"), ktorý popisuje obrázok. To znamená, že ak chcete zaručiť, že sa dostanete na začiatok poľa, musíte napísať:

typedef struct tagBITMAPINFOHEADER
{
DWORD biSize;
DLHÉ biWidth;
DLHÉ biVýška;
dvojplošníky WORD;
SLOVO biBitCount;
DWORD biCompression;
DWORD biSizeImage;
DLHÉ biXPelsPerMeter;
DLHÝ biYPelsPerMeter;
DWORD biClrUsed;
DWORD biClrDôležité;
) BITMAPINFOHEADER, * PBITMAPINFOHEADER;

biSize je veľkosť samotnej konštrukcie. Je potrebné ho inicializovať takto: bih.biSize = sizeof (BITMAPINFOHEADER);
Tu a ďalej budeme predpokladať, že bih je deklarované takto: BITMAPINFOHEADER bih;
biWidth a biHeight nastavte šírku a výšku obrázka v pixeloch, resp.
dvojplošníky nastavuje počet lietadiel. Aj keď je vždy nastavená na 1.
biBitCount- Počet bitov na pixel. Nižšie si o tom povieme podrobnejšie.
biCompression označuje typ kompresie. Nečudujte sa a nezľaknite sa, že v bmp je kompresia. Osobne som nevidel viac ako jeden komprimovaný bmp (ale netvrdím, že taký neexistuje). Ak nedochádza k žiadnej kompresii, tento príznak by mal byť nastavený na BI_RGB. V tomto článku hovoríme o nekomprimovanom formáte, takže ďalšie príznaky ani nebudem uvádzať. Zdá sa, že rovnaká štruktúra je použitá v súboroch JPEG a PNG, pretože od Windows 98 sa objavili možnosti pre BI_JPEG, čo ukazuje, že tento obrázok je JPEG a BI_PNG, že je to PNG (o formáte Jpeg neviem nič, Tieto závery som urobil len na základe toho, čo je napísané v MSDN).
biSizeImage označuje veľkosť obrázka v bajtoch. Ak je obrázok nekomprimovaný (to znamená, že predchádzajúce pole je nastavené na BI_RGB), mala by sa sem zapísať nula. biXPelsPerMeter a biYPelsPerMeter označujú horizontálne a vertikálne rozlíšenie (v pixeloch na meter) konečného zariadenia, do ktorého bude bitmapa (raster) vyvedená. Aplikácia môže použiť túto hodnotu na výber najvhodnejšej bitovej mapy pre požadované zariadenie zo skupiny prostriedkov. Faktom je, že formát bmp je v podstate raster nezávislý na zariadení, to znamená, že vzhľad toho, čo sa získa, nezávisí od toho, na čo sa tento raster (takpovediac) premieta. Napríklad obrázok bude vyzerať rovnako bez ohľadu na to, či je nakreslený na obrazovke monitora alebo vytlačený na tlačiarni. Rozlíšenie zariadení je však iné a tieto parametre sa používajú na výber najvhodnejšieho obrazu z dostupných.
biClrUsed určuje počet použitých farieb z tabuľky. Ak je táto hodnota nula, potom raster používa maximálny počet farieb povolený hodnotou biBitCount. Toto je relevantné len pre komprimované obrázky. Ak je hodnota biClrUsed nenulová a hodnota biBitCount je menšia ako 16, potom hodnota biClrUsed určuje aktuálny počet farieb pre grafický engine alebo dostupný ovládač zariadenia. Ak je hodnota biBitCount väčšia alebo rovná 16, potom biClrUsed určuje veľkosť tabuľky farieb použitej na optimalizáciu aktuálnej systémovej palety.
biClrDôležité je počet dôležitých farieb. Určuje počet farieb, ktoré sú potrebné na zobrazenie kresby. Ak je táto hodnota 0 (ako je to zvyčajne), všetky farby sa považujú za dôležité.

formáty BMP

Všetky druhy formátu bmp podmienečne možno rozdeliť na dva typy: paletové a nepaletové. To znamená, či sa paleta používa v tomto formáte alebo nie. Všimnite si, že paleta môže byť aj v bezpaletových formátoch, len tam sa nepoužíva. V bezpaletových súboroch bmps sa farba vypočítava priamo z bitov, ktoré sú v súbore, počnúc od nejakého miesta. A v palete každý bajt opisuje jeden alebo viac pixelov a hodnoty bajtu (alebo bitov) sú index farieb v palete. Na začiatok uvediem tabuľku, ktorá porovnáva možné možnosti. Typ obrázka (paleta alebo nepaleta) závisí od počtu bitov na pixel, teda od hodnoty biBitCount štruktúry BITMAPINFOHEADER.

biBitCountPaletový alebo nepaletový formátMaximálny možný počet fariebPoznámky (upraviť) 1 Paleta2 Pozor, dvojfarebný, nie nevyhnutne čiernobiely, paletový obrázok. Ak je bit rastra (čo je tesne pod) vymazaný (rovnajúci sa 0), potom to znamená, že toto miesto by malo byť prvou farbou z palety, a ak je nastavené (rovná sa 1), potom druhou farbou . 4 Paleta16 Každý bajt popisuje 2 pixely. Tu je príklad z MSDN: Ak je prvý bajt na obrázku 0x1F, potom zodpovedá dvom pixelom, farba prvého je druhá farba z palety (pretože sa počíta od nuly) a druhý pixel je 16. farba palety. 8 Paleta256 Jedna z najbežnejších možností. Ale zároveň tie najjednoduchšie. Paletka zaberá jeden kilobajt (ale radšej s tým nerátať). Jeden bajt je jedna farba. Jeho hodnota je navyše číslo farby v palete. 16 Bez palety2 ^ 16 alebo 2 ^ 15Toto je najviac mätúca možnosť. Začnime tým, že je bez palety, teda každé dva bajty (jedno SLOVO) v rastri jednoznačne definujú jeden pixel. Ale stane sa toto: existuje 16 bitov a 3 farebné zložky (červená, zelená, modrá). A 16 sa v žiadnom prípade nechce deliť 3. Preto sú tu dve možnosti. Prvým je použiť nie 16, ale 15 bitov, potom sa použije 5 bitov pre každú farebnú zložku. Môžeme teda použiť maximálne 2 ^ 15 = 32768 farieb a výsledkom je trojité R-G-B = 5-5-5. Ale potom sa márne stráca celý kúsok zo 16. Ale stalo sa, že naše oči vnímajú zelenú farbu lepšie spomedzi všetkých farieb, a tak sme sa rozhodli dať tento jeden kúsok zelenej zložke, čiže potom dostaneme trojku RGB = 5-6-5 a teraz môžeme použiť 2 ^ 16 = 65536 farieb. Najnepríjemnejšie však je, že sa využívajú obe možnosti. MSDN navrhuje, aby sa rozlíšilo, koľko farieb sa používa, vyplniť pole biClrUsed zo štruktúry BITMAPINFOHEADER touto hodnotou. Na výber každého komponentu použite nasledujúce masky. Pre formát 5-5-5: 0x001F pre modrú zložku, 0x03E0 pre zelenú a 0x7C00 pre červenú. Pre formát 5-6-5: 0x001F je modrá, 0x07E0 je zelená a 0xF800 je červená. 24 Bez palety2^24 A toto je najjednoduchší formát. Tu 3 bajty definujú 3 farebné zložky. Teda podľa komponentov na bajt. Len čítame štruktúru RGBTRIPLE a používame jej polia rgbtBlue, rgbtGreen, rgbtRed. Idú v tomto poradí. 32 Bez palety2^32 Tu 4 bajty definujú 3 komponenty. Pravdou však je, že jeden bajt sa nepoužíva. Môže byť uvedený napríklad pre alfa kanál (transparentnosť). Čítanie rastra je v tomto prípade pohodlné so štruktúrami RGBQUAD, ktoré sú opísané nasledovne:

Ukladanie údajov vo formáte bmp

No a tu sa dostávame k tomu najzaujímavejšiemu. Po štruktúrach BITMAPFILEHEADER a BITMAPINFOHEADER prichádza paleta. Navyše, ak je formát bez palety, nemusí existovať, ale s tým by sa nemalo počítať. Faktom je, že keď som ešte len začínal riešiť formát bmp, v jednej knihe som čítal, že vraj ak je formát bez palety, tak nemá žiadnu paletu. Boli tam dokonca dva obrázky – formátové diagramy: jeden s paletou, druhý bez. A v tom čase som písal program, ktorý pilne pracuje s BMP. A musel som previesť prichádzajúce 256-farebné obrázky na 24-bitové (ak existujú) v dočasných súboroch. A jednoducho som nevytvoril 24-bitovú paletu (bfOffBits zo štruktúry BITMAPFILEHEADER sa rovnal súčtu sizeof (BITMAPFILEHEADER) + sizeof (BITMAPINFOHEADER) a prichádzajúce 24-bitové som nechal nezmenené. S 256-farebnými rastrami, všetko fungovalo ako má,pričom som nenarazil na 24-bitový obrázok so smetím dole namiesto požadovanej časti.Hneď som nechápal o čo ide.Kým som neporovnal veľkosť pôvodného súboru s tú teoretickú, ktorá by mala byť, keby tam paleta nebola.Rozdiel vyšiel presne 1Kb (presne 1024 bajtov).Paletka tam bola.Nikdy sa preto nespoliehajte na to, či paletka existuje a nespoliehajte sa na jeho veľkosť (hoci všetky obrázky, na ktoré som narazil, mali veľkosť palety 256 farieb alebo 1 kB), vždy prejdite súborom na začiatok rastra pomocou bfOffBits. Paleta je pole štruktúr RGBQUAD nasledujúcich po Iné. Aj keď v palete nie sú použité všetky farby (ale napríklad iba 16), často je pre paletu stále vyhradených 256 polí. A 256 * 4 = 10 24, kde 4 je veľkosť štruktúry RGBQUAD, to znamená, že sa získa rovnaký jeden kilobajt.

Samotný raster sleduje paletu. Toto je viac mätúce. Najprv sú tu popísané pixely, ako je napísané v tabuľke vyššie, v závislosti od formátu. A samotné môžu obsahovať hodnotu farebných komponentov (pre nepalety), alebo môžu byť indexmi poľa-palety. Samotný obrázok sa zaznamenáva riadok po riadku. Po druhé, obraz sa zdá byť otočený hore nohami. To znamená, že najskôr sa píše spodný riadok, potom predposledný riadok a tak ďalej až úplne hore. A po tretie, ako je napísané, ak veľkosť rastrového riadku nie je násobkom 4, potom sa vyplní 1 až 3 prázdnymi (nulovými) bajtmi, takže dĺžka riadku je násobkom odseku. Toto je najnepríjemnejšia vec. Faktom je, že pre každý formát musíte upraviť tento počet prázdnych bajtov (hoci rád tam píšem časť palety, len sa mi nechce pridávať extra "nulové" premenné, ak majú stále povolené prechádzať a nikto ich nepotrebuje). Dávam tabuľku so vzorcami, ktoré ukazujú, pre ktorý formát, koľko bajtov by sa malo pripojiť na koniec riadku. Tam premenná Width, ako by ste mohli hádať, znamená šírku obrázka. Všetky tieto vzorce boli stanovené experimentálne. Uvediem len príklad pre najčastejšie používané formáty. Ostatné si môžete napísať sami.

Ukážkové programy

Všetky zdroje si môžete stiahnuť, nebudem tu veľa písať. Dám vám len funkcie s komentármi.

Ahoj 1. Vytvorte obrázok vo formáte bmp.
Tu sa vytvorí monochromatický obraz. V príkladoch sú tri takéto funkcie: vytváranie bmp 8, 16 a 24 bitov. Budem citat len ​​pre 16-bitove.

// Vytvorte 16-bitový obrázok bmp typu 5-5-5, ktorý bude iba monochromatický
void CreateBmp555 (char * fname, farba SLOVA)
{
HANDLE hFile;
DWORD RW;
int i, j;

// Deklarujte požadované štruktúry
BITMAPFILEHEADER bfh;
BITMAPINFOHEADER bih;
Paleta BYTE [1024]; // Paleta

// Majme obrázok s rozmermi 35 x 50 px
int šírka = 35;
int Výška = 50;

memset (paleta, 0, 1024); // V palete ich vyplníme nulami
memset (& bfh, 0, sizeof (bfh));

Bfh.bfType = 0x4D42; // Označme, že toto je bmp "BM"
bfh.bfOffBits = sizeof (bfh) + sizeof (bih) + 1024; // Paleta má 1Kb, ale nevyužijeme ju
bfh.bfSize = bfh.bfOffBits +
sizeof (farba) * Šírka * Výška +
Výška * ((veľkosť (farba) * Šírka)% 4); // Vypočítajte veľkosť konečného súboru
memset (& bih, 0, sizeof (bih));
bih.biSize = sizeof (bih); // Takto to má byť
bih.biBitCount = 16; // 16 bitov na pixel
bih.biClrUsed = 32768; // Používame 5-5-5
bih.biCompression = BI_RGB; // Bez kompresie
bih.biHeight = Výška;
bih.biWidth = šírka;
bih.biPlanes = 1; // Malo by byť 1
// A zvyšok polí zostane 0

HFfile = CreateFile (fname, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
if (hFile == INVALID_HANDLE_VALUE)
návrat;

// Napíšte hlavičky
WriteFile (hFile, & bfh, sizeof (bfh), & RW, NULL);
WriteFile (hFile, & bih, sizeof (bih), & RW, NULL);

// Napíšte paletu
WriteFile (hFile, Palette, 1024, & RW, NULL);
pre (i = 0; i< Height; i++ )
{
pre (j = 0; j< Width; j++ )
{
WriteFile (hFile, & color, sizeof (color), & RW, NULL);
}

// Zarovnanie podľa okraja
WriteFile (hFile, Palette, (veľkosť (farba) * Šírka)% 4, & RW, NULL);
}
CloseHandle (hFile);
}

farba - farba obrázku. Hodnotu tejto premennej je potrebné vyplniť podľa prvej tabuľky. Výsledný obrázok si môžete pozrieť napríklad v ACDSee. Skúsil som to otvoriť vo Photoshope, ale ukázalo sa, že ich nevie prečítať v tomto formáte. Ale môžete :).

Príklad 2. Prevod obrázka z 8 bitov (256 farieb) na 24 bitov.

BOOL Convert256To24 (char * fin, char * fout)
{
BITMAPFILEHEADER bfh;
BITMAPINFOHEADER bih;
int Šírka, Výška;
Paleta RGBQUAD [256];
BYTE * inBuf;
RGBTRIPLE * outBuf;
RUKOJEŤ hIn, hOut;
DWORD RW;
DWORD OffBits;
int i, j;

HIn = CreateFile (fin, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
if (hIn == INVALID_HANDLE_VALUE)
návrat FALSE;

Hout = CreateFile (fout, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
if (hOut == INVALID_HANDLE_VALUE)
{
CloseHandle (hIn);
návrat FALSE;
}

// Prečítajte si údaje
ReadFile (hIn, & bfh, sizeof (bfh), & RW, NULL);
ReadFile (hIn, & bih, sizeof (bih), & RW, NULL);
ReadFile (hIn, Palette, 256 * sizeof (RGBQUAD), & RW, NULL);

// Nastavíme ukazovateľ na začiatok rastra
SetFilePointer (hIn, bfh.bfOffBits, NULL, FILE_BEGIN);
Width = bih.biWidth;
Výška = bih.biVýška;
OffBits = bfh.bfOffBits;

// Pridelenie pamäte
inBuf = nový BYTE [Šírka];
outBuf = nový RGBTRIPLE [Šírka];

// Vyplňte hlavičky
bfh.bfOffBits = sizeof (bfh) + sizeof (bih); // Paletu nenapíšeme
bih.biBitCount = 24;
bfh.bfSize = bfh.bfOffBits + 4 * Šírka * Výška + Výška * (Šírka % 4); // Veľkosť súboru

// A ostatné sa nemení
// Napíšte hlavičky
WriteFile (hOut, & bfh, sizeof (bfh), & RW, NULL);
WriteFile (hOut, & bih, sizeof (bih), & RW, NULL);

// Začnite transformovať
pre (i = 0; i< Height; i++ )
{
ReadFile (hIn, inBuf, Width, & RW, NULL);
pre (j = 0; j< Width; j++ )
{
outBuf [j] .rgbtČervená = Paleta [inBuf [j]] .rgbČervená;
outBuf [j] .rgbtGreen = Paleta [inBuf [j]] .rgbGreen;
outBuf [j] .rgbtBlue = Paleta [inBuf [j]] .rgbBlue;
}
WriteFile (hOut, outBuf, sizeof (RGBTRIPLE) * Width, & RW, NULL);

// Napíšte odpad na zarovnanie
WriteFile (hOut, Palette, Width% 4, & RW, NULL);
SetFilePointer (hIn, (3 * šírka)% 4, NULL, FILE_CURRENT);
}

vymazať inBuf;
vymazať outBuf;
CloseHandle (hIn);
CloseHandle (hOut);
vrátiť TRUE;
}

Názvy zdrojových a cieľových súborov musia byť odovzdané funkcii, resp.

Formát súboru BMP (skrátene BitMaP) je natívny bitmapový grafický formát pre Windows, pretože sa najviac zhoduje s interným formátom Windows, v ktorom systém ukladá svoje bitmapové polia. Prípona BMP sa najčastejšie používa pre názvy súborov vo formáte BMP, hoci niektoré súbory majú príponu RLE, čo znamená kódovanie dĺžky spustenia. Prípona súboru RLE zvyčajne označuje, že informácie o bitovej mape súboru boli komprimované pomocou jednej z dvoch metód kompresie RLE, ktoré sú dostupné pre súbory BMP.

V súboroch BMP je informácia o farbe každého pixelu zakódovaná 1, 4, 8, 16 alebo 24 bitov (bitov na pixel). Bity / pixel, tiež nazývané farebná hĺbka, predstavujú maximálny počet farieb v obrázku. Obrázok s rýchlosťou 1 bit / pixel môže mať iba dve farby, zatiaľ čo pri rýchlosti 24 bit / pixel môže mať viac ako 16 miliónov rôznych farieb.

Nižšie uvedený diagram zobrazuje štruktúru typického súboru BMP obsahujúceho 256-farebný obrázok (s hĺbkou 8 bitov/pixel). Súbor je rozdelený do štyroch hlavných častí: hlavička bitmapového súboru, informačná hlavička bitmapy, tabuľka farieb a samotné bitmapové údaje. Hlavička súboru rastrovej grafiky obsahuje informácie o súbore vrátane adresy, na ktorej začína oblasť údajov rastrového poľa. Informačná hlavička rastrového poľa obsahuje informácie o obrázku uloženom v súbore, ako je jeho výška a šírka v pixeloch. Tabuľka farieb zobrazuje hodnoty základných farieb RGB (červená, zelená, modrá) pre farby použité na obrázku. Programy, ktoré čítajú a zobrazujú súbory BMP, môžu v prípade použitia video adaptérov, ktoré nedokážu zobraziť viac ako 256 farieb, programovo nastaviť takéto hodnoty RGB v paletách farieb adaptéra pre presnú reprodukciu farieb.

Formát skutočných údajov bitmapy v súbore BMP závisí od počtu bitov použitých na kódovanie farebných údajov pre každý pixel. Pri 256-farebnom obrázku je každý pixel v časti súboru, ktorá obsahuje skutočné údaje rastrového poľa, opísaný jedným bajtom (8 bitov). Tento popis pixelov nepredstavuje hodnoty farieb RGB, ale slúži skôr ako ukazovateľ na vstup do tabuľky farieb súboru. Ak je teda R / G / B = 255/0/0 uložená ako prvá hodnota farby RGB v tabuľke farieb súboru BMP, potom sa hodnota pixelu 0 v poli rastrov namapuje na jasne červenú. Hodnoty pixelov sú uložené v poradí zľava doprava, začínajúc (zvyčajne) v spodnej časti obrázka. V súbore BMP s 256 farbami je teda prvý bajt rastrových údajov indexom farby pixelu v ľavom dolnom rohu obrázka; druhý bajt predstavuje index pre farbu nasledujúceho pixelu vpravo atď.. Ak je počet bajtov v každom riadku nepárny, do každého riadka sa pridá bajt navyše, aby sa údaje bitovej mapy zarovnali na 16-bitových hraniciach.


Nie všetky súbory BMP majú štruktúru zobrazenú na obrázku. Napríklad súbory BMP s veľkosťou 16 a 24 bpc nemajú tabuľky farieb; v týchto súboroch hodnoty pixelov rastrového poľa priamo charakterizujú hodnoty farieb RGB. Taktiež sa môžu líšiť formáty interného úložiska jednotlivých častí súboru. Napríklad bitmapové informácie v niektorých súboroch BMP so 16 a 256 farbami možno komprimovať pomocou algoritmu RLE, ktorý nahrádza sekvencie identických obrazových bodov tokenmi, ktoré určujú počet obrazových bodov v sekvencii a ich farbu. V systéme Windows môžete pracovať so súbormi BMP v štýle OS / 2, ktoré používajú rôzne formáty rastrových hlavičiek a tabuliek farieb.

Ako skryť text v bitmapovom obrázku. Žiaľ, nenašiel som žiadne témy na túto tému a rozhodol som sa vyplniť túto medzeru. Pod výrezom nájdete spôsob, ako skryť text v bitmape, ako aj implementáciu v C #.

Formulácia problému

Skryť ľubovoľný text zakódovaný systémom Windows-1251 do 24-bitového bitmapového obrázka a skresliť ho späť bez skreslenia.

Štruktúra súboru BMP

Najprv mi dovoľte pripomenúť, čo je to bitmapový súbor. Som si istý, že to všetko dobre poznáte, len bude jasnejšie popísať algoritmus skrývania textu na základe prezentovaného materiálu. Takže Každý súbor bmp pozostáva zo štyroch častí:
  1. Hlavička súboru
  2. Názov obrázka (môže chýbať)
  3. Paleta (nemusí byť prítomná)
  4. Samotný obraz
Hlavička súboru obsahuje servisné informácie vrátane bitovej hĺbky obrazu. Mimochodom, paleta sa nepoužíva na 24-bitovú kresbu. Keďže sme v zadaní jasne uviedli, že budeme pracovať len s 24-bitovými obrázkami, ideálne je, ak si môžete skontrolovať, či vstupný obrázok spĺňa požiadavky.
Teraz prejdime priamo k samotnému obrázku. Ako viete, formát bmp štandardne neposkytuje kompresiu (hoci podporuje kompresiu RLE). Každý pixel je teda v našom prípade zakódovaný 24 bitmi, jeden bajt pre každú farebnú zložku. Preto nemôžeme zakódovať viac, ani menej, ale presne 16 777 216 farieb. Pre prehľadnosť uvediem obrázok:

Myšlienka algoritmu skrývania textu

Pravdepodobne ste už uhádli, čo je to za nápad. Ide o to, že oko priemerného človeka (nie profesionálneho umelca či fotografa) rozlišuje oveľa menej farieb, ako bolo naznačené vyššie. Ani jedna kniha nemá jasnú odpoveď na otázku, koľko farieb dokáže oko rozlíšiť, ale najväčší údaj, s ktorým som sa stretol, je 10 miliónov. Z toho vyplýva, že niekoľko najmenej významných bitov z ôsmich pridelených každej farebnej zložke možno si požičať na naše žoldnierske ciele.
Niekoľko čísel: napríklad zoberme a drzo odpočítajme dva najmenej významné bity od komponentov RGB. To znamená, že z 24 bitov budeme mať 18, pomocou ktorých možno zakódovať presne 262 144 farieb. Teraz si vezmime text v kódovaní windows-1251, v ktorom je každý znak reprezentovaný 8 bitmi. Pomocou jednoduchej matematiky zistíme, že do 4 pixelov možno uložiť 3 znaky. Na obrázku 1024x768, kde je 786432 pixelov, je teda možné uložiť 589824 znakov. Nie je to zlé, čo? Pre prehľadnosť uvediem dva obrázky. Prvý je pôvodný obrázok a druhý je obrázok, na ktorom sú najmenej dva bity každej farebnej zložky vyplnené textom. Okamžite urobím rezerváciu, aby sa obrázky previedli do formátu png, aby sa ušetrila premávka.

Pôvodný obrázok:


Obrázok obsahujúci text


Ak sa pozriete pozorne, farby sa na druhom obrázku zdajú matnejšie. Áno, je. Vy aj ja však vieme, že na prezentovanom obrázku niečo nie je v poriadku a keby sme to nevedeli, ani by sme neuhádli, že sa v ňom skrýva nejaký text. Mimochodom, obrázok obsahuje frázu „Ahoj svet !!! =) „Vynásobené 100-krát.
To je všetko. Ako vidíte, myšlienka je veľmi jednoduchá. Mimochodom, prezentovaná metóda sa nazýva LSB (vďaka za radu). Nakoniec môžete vidieť implementáciu v C #.

C # implementácia

Prezentovaná implementácia si nenárokuje na kódovo dokonalé ocenenie, iba demonštruje popísaný algoritmus v praxi. V tomto prípade som sa nehnal za krásou kódu, ale za prehľadnosťou.