如何通過UltraEdit解析BMP文件內(nèi)部結(jié)構(BMP位圖基礎)
初見位圖
我們先打開畫圖隨便畫一幅圖并采用24位bmp圖像格式保存,就得到了一張24位真彩色的位圖
BMP位圖一般由4部分組成:文件頭信息塊、圖像描述信息塊、顏色表(在真彩色模式無顏色表)和圖像數(shù)據(jù)區(qū)組成,以BMP為擴展名保存。
打開Windows的畫圖程序,在保存圖像時,可以看到三個選項:2色位圖(黑白)、16色位圖、256色位圖和24位位圖。這是最普通的生成位圖的工具,在這里講解的BMP位圖形式,主要就是指用畫圖生成的位圖. 一般的bmp圖像都是24位,也就是真彩。每8位為一字節(jié),24位也就是使用三字節(jié)來存儲每一個像素的信息,三個字節(jié)對應存放r,g,b三原色的數(shù)據(jù)每個字節(jié)的存貯范圍都是0-255。那么以此類推,32位圖即每像素存儲r,g,b,a(Alpha通道,存儲透明度)四種數(shù)據(jù)。8位圖就是只有灰度這一種信息,還有二值圖,它只有兩種顏色,黑或者白。
接下來逐個分析BMP位圖的各個組成部分
位圖文件的基本結(jié)構
1.文件頭信息塊
文件信息頭 (14字節(jié))存儲文件類型,文件大小等信息
// 文件信息頭結(jié)構體 typedef struct tagBITMAPFILEHEADER { unsigned short bfType; // 19778,必須是BM字符串,對應的十六進制為0x4d42,十進制為19778,否則不是bmp格式文件 unsigned int bfSize; // 文件大小 以字節(jié)為單位(2-5字節(jié)) unsigned short bfReserved1; // 保留,必須設置為0 (6-7字節(jié)) unsigned short bfReserved2; // 保留,必須設置為0 (8-9字節(jié)) unsigned int bfOffBits; // 從文件頭到像素數(shù)據(jù)的偏移 (10-13字節(jié)) } BITMAPFILEHEADER;
2.圖像描述信息塊
圖片信息頭 (40字節(jié))存儲著圖像的尺寸,顏色索引,位平面數(shù)等信息
//圖像信息頭結(jié)構體 typedef struct tagBITMAPINFOHEADER { unsigned int biSize; // 此結(jié)構體的大小 (14-17字節(jié)) long biWidth; // 圖像的寬 (18-21字節(jié)) long biHeight; // 圖像的高 (22-25字節(jié)) unsigned short biPlanes; // 表示bmp圖片的平面屬,顯然顯示器只有一個平面,所以恒等于1 (26-27字節(jié)) unsigned short biBitCount; // 一像素所占的位數(shù),一般為24 (28-29字節(jié)) unsigned int biCompression; // 說明圖象數(shù)據(jù)壓縮的類型,0為不壓縮。 (30-33字節(jié)) unsigned int biSizeImage; // 像素數(shù)據(jù)所占大小, 這個值應該等于上面文件頭結(jié)構中bfSize-bfOffBits (34-37字節(jié)) long biXPelsPerMeter; // 說明水平分辨率,用象素/米表示。一般為0 (38-41字節(jié)) long biYPelsPerMeter; // 說明垂直分辨率,用象素/米表示。一般為0 (42-45字節(jié)) unsigned int biClrUsed; // 說明位圖實際使用的彩色表中的顏色索引數(shù)(設為0的話,則說明使用所有調(diào)色板項)。 (46-49字節(jié)) unsigned int biClrImportant; // 說明對圖象顯示有重要影響的顏色索引的數(shù)目,如果是0,表示都重要。(50-53字節(jié)) } BITMAPINFOHEADER;
3.顏色表
調(diào)色板 (由顏色索引數(shù)決定)(可以沒有此信息,下面的例子就因為采用了24位真彩色保存所以沒有這部分信息)
//24位圖像素信息結(jié)構體,即調(diào)色板 typedef struct _PixelInfo { unsigned char rgbBlue; //該顏色的藍色分量 (值范圍為0-255) unsigned char rgbGreen; //該顏色的綠色分量 (值范圍為0-255) unsigned char rgbRed; //該顏色的紅色分量 (值范圍為0-255) unsigned char rgbReserved;// 保留,必須為0 } PixelInfo;
4.圖像數(shù)據(jù)區(qū)
位圖數(shù)據(jù) (由圖像尺寸決定)每一個像素的信息在這里存儲
顏色表接下來位為位圖文件的圖像數(shù)據(jù)區(qū),在此部分記錄著每點像素對應的顏色號,其記錄方式也隨顏色模式而定,既2色圖像每點占1位(8位為1字節(jié));16色圖像每點占4位(半字節(jié));256色圖像每點占8位(1字節(jié));真彩色圖像每點占24位(3字節(jié))。所以整個數(shù)據(jù)區(qū)的大小也會隨之變化。究其規(guī)律而言,可的出如下計算公式:圖像數(shù)據(jù)信息大小=(圖像寬度 * 圖像高度 * 記錄像素的位數(shù))/8。
具體例子
右鍵單擊我們開頭畫的圖片可以查看該圖片的分辨率,寬度,高度和位深度。為1152 * 648像素。這是一張24位真彩色位圖。1152 * 648 = 746496像素,746496像素 * 24位/像素 / (8 * 1024 * 1024)位 =2.13 MB,與顯示的圖片大小相符。
接下來用UltraEdit打開這張BMP圖像,顯示的是十六進制的代碼
現(xiàn)在我們來讀取這些代碼,看看他們到底保存了一些啥東西。 在這里要注意的是
Windows的數(shù)據(jù)是倒著念的,這是PC電腦的特色。如果一段數(shù)據(jù)為42 4D,倒著念就是4D 42,即0x4D42。 因此,如果bfSize的數(shù)據(jù)為A2 1E 04 00,實際上就成了0x00041EA2,也就是0x41EA2。
參照上面的文件信息頭結(jié)構體內(nèi)容對這幅位圖的內(nèi)容進行分析。文件信息頭結(jié)構體第一個數(shù)據(jù)是unsigned short(16位)類型的bfType變量。觀察十六進制代碼結(jié)果可以看到第一行開頭的42 4D倒著念就是4D 42(剛好16位對應unsigned short類型),即bftype=0x4D42(轉(zhuǎn)換為十進制為19778,實際上所有BMP圖像的bfType對應屬性都是這個值)。按照這個方法可得出第二個數(shù)據(jù)bfSize類型為unsigned int(32位),圖中對應的十六進制代碼為00222C36(轉(zhuǎn)換為十進制為2239542),這代表文件大小為2239542字節(jié)=2.13MB,和我們在剛剛屬性欄里的文件大小完全相等。
接下來利用類似的方法可以從十六進制代碼中得到這張位圖的文件頭信息塊和圖像描述信息塊所存儲的信息
unsigned short bfType = 0x4D42 = 19778 unsigned int bfSize = 0x00222C36 = 2239542字節(jié)=269986/(1024*1024)=2.13MB unsigned short bfReserved1 = 00 00 unsigned short bfReserved2 = 00 00 unsigned int bfOffBits = 0X00000036 = 0x36 = 54字節(jié) unsigned int biSize = 0x00000028 = 0x28 = 40字節(jié)(圖像信息頭結(jié)構體大小就是40字節(jié)) long biWidth = 0x00000480 = 0x480 = 1152像素; long biHeight = 0x00000288 = 0x288 = 648像素 ; unsigned short biPlanes = 0x0001 = 0x1 = 1; unsigned short biBitCount = 0x0018 = 0x18 = 24位; unsigned int biCompression = 0x00000000 = 0; unsigned int biSizeImage = 0x00222C00 = 0;(等于bfSize-bfOffBits) long biXPelsPerMeter = 0x00000000 = 0; long biYPelsPerMeter = 0x00000000 = 0; unsigned int biClrUsed = 0x00000000 = 0; unsigned int biClrImportant = 0x00000000 = 0; /*因為采用了24位真彩色格式保存,所以沒有顏色表信息。緊跟著上述文件頭信息塊和圖像 描述信息塊存儲的信息的就是圖像數(shù)據(jù)區(qū)的信息。每一個像素為24位,即3字節(jié),例如緊跟著 的FFFFFF這三個字節(jié)就代表白色*/
到此這篇關于如何通過UltraEdit解析BMP文件內(nèi)部結(jié)構(BMP位圖基礎:)的文章就介紹到這了,更多相關UltraEdit BMP位圖文件內(nèi)部結(jié)構內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
C#將Unicode編碼轉(zhuǎn)換為漢字字符串的簡單方法
下面小編就為大家?guī)硪黄狢#將Unicode編碼轉(zhuǎn)換為漢字字符串的簡單方法。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-01-01C++?vector與數(shù)組轉(zhuǎn)換寫入/讀出文件方式
這篇文章主要介紹了C++?vector與數(shù)組轉(zhuǎn)換寫入/讀出文件方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-11-11C++實現(xiàn)LeetCode(188.買賣股票的最佳時間之四)
這篇文章主要介紹了C++實現(xiàn)LeetCode(188.買賣股票的最佳時間之四),本篇文章通過簡要的案例,講解了該項技術的了解與使用,以下就是詳細內(nèi)容,需要的朋友可以參考下2021-08-08C語言利用system調(diào)用系統(tǒng)命令行詳情
這篇文章主要介紹了C語言利用system調(diào)用系統(tǒng)命令行詳情,system就是調(diào)用系統(tǒng)命令行,輸入為字符串,然后把這個字符串輸出給命令行,讓命令行執(zhí)行。下文的具體內(nèi)容,需要的小伙伴可以參考一下2022-01-01C語言實現(xiàn)食堂就餐管理系統(tǒng)(帶鏈表)
這篇文章主要為大家詳細介紹了C語言實現(xiàn)食堂就餐管理系統(tǒng),文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2019-11-11