C語言結構體描述BMP的文件格式

2021-01-20 酷扯兒

本文轉載自【微信公眾號:strongerHuang,ID:strongerHuang】經微信公眾號授權轉載,如需轉載與原文作者聯繫

BMP文件的結構其實非常簡單,就是兩個結構體+一個可選的調色板+位圖數據。

第一個結構體是BITMAPFILEHEADER,第二個結構體是BITMAPINFOHEADER。然後就是可選的調色板(RGBQUAD數組)。最後是位圖數據。

1

第一個結構體

這裡先講講第一個結構體位圖文件頭結構:BITMAPFILEHEADER 的詳細結構。

先看看代碼原型:

typedef struct tagBITMAPFILEHEADER

{

WORD bfType;

DWORD bfSize;

WORD bfReserved1;

WORD bfReserved2;

DWORD bfOffBits;

} BITMAPFILEHEADER, *PBITMAPFILEHEADER;

其中:

bfType:文件的標識,值必須是0x4D42(也就是「BM」兩個字符,注意是Little-Endian)

bfSize:是整個文件的大小

bfReserved1和bfReserved2必須是0.

bfOffBits:是位圖數據在文件中的偏移。

2

第二個結構體

位圖信息頭:BITMAPINFOHEADER。

typedef struct tagBITMAPINFOHEADER

{

DWORD biSize;

LONG biWidth;

LONG biHeight;

WORD biPlanes;

WORD biBitCount;

DWORD biCompression;

DWORD biSizeImage;

LONG biXPelsPerMeter;

LONG biYPelsPerMeter;

DWORD biClrUsed;

DWORD biClrImportant;

} BITMAPINFOHEADER, *PBITMAPINFOHEADER;

biSize:

BITMAPINFOHEADER這個結構體的大小。必須為40(字節)。

biWidth:

BMP位圖的寬度。

biHeight:

BMP位圖的寬度。

這裡需要說明一下的是,BMP位圖數據有兩種存儲方式,通常是「底到上型」,也就是BMP位圖數據的第一行其實是這個圖片的最後一行。一種是「頂到下型」,BMP位圖數據的第一行就是圖片的第一行。

如果位圖是「頂到下型」,那麼biHeight的值是負的,位圖的實際高度其實是(-biHeight),也就是它的相反數。

只有「底到上型」位圖支持壓縮。「底到上型」是目前最常見的位圖類型。

PhotoShop在保存位圖文件的時候,你可以設置讓它輸出「底到上型」或「頂到下型」。「頂到下型」就是「逆行序」。

biPlanes:

位圖的「位面數」。這個值必須為1.

biBitCount:

位圖的「顏色位數」。表示位圖數據中,幾個二進位位表示一個像素。

顏色位數為1表示單色(其實是「雙色」,通常是黑白,也可以是別的兩個顏色。)

為2表示四色,也就是四種顏色。為4表示16種顏色。為8表示有256種顏色。

在表示256色以內的顏色數量的時候,這個BMP文件其實是作為使用調色板顏色的圖像,因此在BITMAPINFOHEADER結構體的後面還有個調色板。

所謂調色板其實就是RGBQUAD結構體的數組。它的元素個數就是顏色數。

biCompression:

位圖的壓縮格式,值可以是BI_RGB(未壓縮),BI_RLE8(8位RLE壓縮),BI_RLE4(4位RLE壓縮),BI_BITFIELDS(表示顏色表中,每個像素有3個DWORD的屏蔽位數據來指示紅綠藍成分。16位和32位位圖可以使用這個。),BI_JPEG(位圖數據其實是JPG格式的),BI_PNG(位圖數據其實是PNG格式的)

當biCompression值為BI_RLE8的時候,biBitCount必須為8,表示這是個8位的256色索引顏色位圖(有256個調色板),位圖數據按照如下算法壓縮:

·位圖數據是每兩個字節組成一個元素,這樣的元素組成了一個數組。

·每個元素,第一個字節表示重複的像素的數量,第二個字節是8位的調色板顏色索引。

·如果元素的第一個字節為0,那麼第二個字節有特殊的含義:

0:這行已經結束了。

1:這個位圖已經結束了。

2:設置下一個像素的位置,後面的兩個無符號字節分別指定了下一個像素的X、Y偏移。注意是無符號字節,意思是說,偏移只能是往後。

3到0xFF:表示後面有一段沒有壓縮的數據的長度,也就是連續的8位像素顏色索引數據的長度。但是數據必須是2位元組對齊的。biCompression值為BI_RLE4的時候,biBitCount必須為4,表示這是個4位的16色索引顏色位圖(有16個調色板)。

和BI_RLE8的區別只是每個元素的第二個字節如果表示顏色索引,它表示的是兩個像素的顏色索引。第一個字節表示重複的數量,第二個字節表示兩個像素的顏色。

舉個例,假設調色板第0號色是黑色,第1號色是白色,元素的值是0x05,0x01,那麼它表示「黑白黑白黑白黑白黑白」共10個像素出現在1行。

biSizeImage:

位圖數據塊的大小。以字節為單位。如果你的位圖沒有經過壓縮,這個值可以是0.

biXPelsPerMeter:

表示橫向的每米的像素數。可以為0.

biYPelsPerMeter:

表示縱向的每米的像素數。可以為0.

biClrUsed:

位圖實際使用過的調色板的顏色數。如果這個值為0,表示這個位圖使用了整個調色板。只有8位以及8位以下的索引顏色位圖才需要考慮這個值。對於16位以及16位以上的位圖,無視這個值。biClrImportant表示重要的顏色數。如果為0,表示顏色都重要。通常它的值等於biClrUsed,或者等於0.

如果位圖是8位以及8位以下的位圖,後面是位圖的調色板數據。否則沒有調色板數據。

調色板就是簡單的RGBQUAD數組。

後面就是位圖數據了。如果位圖是沒有經過壓縮的,那麼位圖數據的存儲就是一行一行的,每行都是每XX個字節一個像素,取決於位圖的位數(biBitCount),每一行都是4位元組對齊的!多出來的部分用0補齊。這裡必須注意。

因此,每行佔用的字節數要按照以下公式計算:(其中的biBitCount指的是位圖的位數,也就是BITMAPINFOHEADER的成員)

每行字節數 = ((圖像寬度 - 1) * biBitCount / 32 + 1) * 4;

如果你是用VB編寫讀取位圖的話,是這樣寫的:

每行字節數 = ((圖像寬度 - 1) * biBitCount \ 32 + 1) * 4

這裡還要注意的是「底到上型」位圖和「頂到下型」位圖,如果BITMAPINFOHEADER的biHeight成員大於零,那麼這個位圖就是「底到上型」,否則就是「頂到下型」。「底到上型」的位圖,它的行序是從下到上排列的,也就是逆行序。「頂到下型」位圖行序是從上到下排列的。

3

位圖顏色表

位圖顏色表就比較簡單了:

typedef struct tagRGBQUAD

{

BYTE rgbBlue;

BYTE rgbGreen;

BYTE rgbRed;

BYTE rgbReserved;

} RGBQUAD;

紅祿藍三種顏色,然後還有保留一個字節。

最後,還有位圖數據,這裡就不描述了。

免責聲明:本文部分素材來源網絡,版權歸原作者所有。如涉及作品版權問題,請與我聯繫刪除

相關焦點

  • C語言相關文件的基本知識
    用過計算機的人,對文件都不陌生,大多數人都接觸過,今天我們來講講關於C語言相關文件的基本知識。首先,我們先來了解了解什麼是文件。文件有不同的類型,在程序的設計中,主要有兩種文件; 1.程序文件;包括源程序文件(後綴為.c),目標文件(後綴為.obj),可執行文件(後綴為.exe)等,這類文件的內容是程序代碼。
  • 「記」詳解C語言之格式
    ,在它的主體設計完成後,Thompson和Ritchie用它完全重寫了UNIX,且隨著UNIX的發展,c語言也得到了不斷的完善。為了利於C語言的全面推廣,許多專家學者和硬體廠商聯合組成了C語言標準委員會,並在之後的1989年,誕生了第一個完備的C標準,簡稱「C89」,也就是「ANSI c」,截至2020年,最新的C語言標準為2017年發布的 「C17」。
  • 計算機二級考試C語言高頻考點
    (5)注釋:括在「/*」與「*/」之間,沒有空格,允許出現在程序的任何位置(6)預處理命令:以「#」開頭的語句2.C程序的生成過程(1)C程序是先由源文件經編譯生成目標文件,然後經過連接生成可執行文件。
  • 定義只有一個數組成員的C語言結構體有什麼用?
    C語言代碼示例編譯並執行上述C語言代碼,得到如下輸出:# gcc t.c# .而如果將數組封裝在結構體內部,將結構體作為參數,那麼在函數內部,我們依然可以獲得完整的數組,請看下面的C語言代碼示例:#include <stdio.h>typedef struct{char arr[16];}String;void fun(String *str){printf("sizeof
  • c語言結構體數組初始化
    有關結構體數組初始化的問題struct _m_usmart_nametab usmart_nametab[]=本文引用地址:http://www.eepw.com.cn/article/201611/322298.htm{#if USMART_USE_WRFUNS==1 //如果使能了讀寫操作(void
  • 最全的C語言基礎知識都在這了
    我們用一個簡單的c程序例子,介紹c語言的基本構成、格式、以及良好的書寫風格,加深小夥伴們對C語言的認識。/ sum=a+b; /*把兩個數之和賦值給整型變量sum*/printf(「a=%d,b=%d,sum=%d\n」,a,b,sum); /*把計算結果輸出到顯示屏上*/ }重點說明:1、任何一個c語言程序都必須包括以下格式
  • 「C語言從入門到入土」必備C語言基礎筆記整理
    一、C語言1、什麼是C語言?C語言是人寫機器看的一種語言。C語言是高級語言中的低級語言。C語言貼近硬體。C語言的入門學習比較簡單。源文件怎樣變成可執行文件?表示問號)printf("輸出三個數 :\n%d\n%d\n%d\n",a,b,c); //變量要先定義,後使用。 在這裡使用換行時應注意 寫成格式 「%d\n」//三個數則要書寫三次。它們相連之間不用分號,也不用逗號。
  • C語言|文件指針、fopen()、fscanf()、fclose()
    這是一個簡單的文件系統fscanf()函數的功能是把磁碟文件數據讀出保存到變量(內存)每一個文件都有自己的FILE結構和文件緩衝區exit(0)是系統標準函數,作用是關閉所有打開的文件,並終止程序的執行。
  • R語言中使用scan函數讀取文件中的數據
    (1)scan("student.txt", what="c") #以字符串的格式讀取數據(2)scan("student.txt", what="c", nlines=3) #讀取3行(3)scan("student.txt", what="c", skip=1) #忽略第1行
  • C語言中的「不透明」指針是什麼,它有什麼用呢?
    雖然還沒有具體定義結構體 pmpi_s,但是已經可以使用 pmpi 定義變量了,例如下面這行C語言代碼:pmpi p = NULL;這裡的指針 p 就是一個「不透明指針」,因為我們暫時看不到它到底指向什麼樣的內容,就像一個「不透明」的盒子一樣。
  • 第六篇:C語言中結構體與文件操作相關知識點梳理
    在C語言中結構體是對數據類型的無限擴展。程式設計師可以根據需要定義各種各樣的數據類型,即:結構體。問題二:數據無法永久保存前面我們編寫運行的所有C語言程序,或多或少都會輸入一些數據。有,一種是通過資料庫,另外一種就是通過文件永久保存數據。文件操作將是本文要總結的第二個核心知識點,將程序中的數據永久保存到磁碟上,方便下次讀寫操作。
  • photoshop中有哪些常用的文件格式及其應用
    在photoshop中有很多種文件格式,在這些文件格式中,包含ps的專用格式、用於應用程式交換的文件格式,以及一些特殊格式。下面我們來看一下有哪些常用的文件格式。photoshop中有哪些文件格式及其應用1、PSD格式和PDD格式psd和pdd格式都是ps自帶的專用文件格式,能夠保存各種色彩模式的圖像類型,但由於在其它圖形處理程序中兼容性不好,所以一般只用於ps的源文件存儲
  • 結構體字節對齊詳解(C/C++)
    開篇明義,在討論結構體字節對齊問題前,我們需知道,什麼是結構體,大家可以把結構體比喻成一籮筐,這個籮筐會隨著裡面放的東西的體積的增加而變大
  • 2003年10月甘肅省高等教育自學考試C語言程序設計試卷
    ()  A已讀到此文件末尾 B未讀到此文件的末尾  C此文件已關閉 D此文件尚未被打開  8.以下c語言函數聲明中,不正確的是()  Avoid fun (int x, int y); Bfun (int x, int y);  Cint fun (int x,y); Dchar *fun (char *s);
  • C語言怎麼樣?今天聊聊C語言的發展史!
    > 可以看到基本都是用彙編寫的(文件名後綴.s)。 後面的故事,大家可能也聽說過:後來學術和政府組織中都在使用Unix,也正是由於Unix的風靡與興盛,帶動了C語言被廣泛的傳播、使用。 在1980年代,C語言的使用廣泛傳播,並且幾乎所有機器體系結構和作業系統都可以使用編譯器。
  • iOS13Beta2描述文件在哪下 iOS13開發者測試版描述文件及固件下載...
    iOS13Beta2描述文件在哪下 iOS13開發者測試版描述文件及固件下載地址 北京時間今天凌晨,蘋果發布了 iOS 13 和 iPadOS 等多個系統的開發者預覽版更新,這距離第一個測試版發布僅相隔
  • EPS是什麼格式
    本文引用地址:http://www.eepw.com.cn/article/274013.htm一、EPS是什麼格式- -EPS是什麼?  EPS,全稱為Encapsulated Postscript,又稱為帶有預視圖像的PS格式,是一種跨平臺的標準格式,目前已廣泛應用於計算機桌面印刷系統中。EPS一般由一個PostScript語言的文本文件和PICT或TIFF描述的代表像組成。
  • 自考「C語言程序設計」模擬試題十四
    7.C語言中用於結構化程序設計的三種基本結構是(     )  A.if、switch、break  B.if   while   for  C.while   do- while   for  D.順序結構、選擇結構、循環結構  8.以下敘述中不正確的是(     )  A.在不同的函數中可以使用相同名字的變量
  • 自考「C語言程序設計」模擬試題九
    A.d&ef          B.6a            C.z4x5c           D.a3/b4  3.在C語言中,存儲一個字符型、整型、單精度實型變量所需的空間是()。  int  x;   char  y;   char  z[20];  A. scanf(「%d%c%c」,&x,&y,&z);     B. scanf(「%d%c%s」,&x,&y,&z);  C. scanf(「%d%c%c」,&x,&y,z);
  • png圖片怎樣轉換成jpg格式?利用什麼工具能實現
    圖片格式有很多種,據小編知道的就有jpg, png, gif, jpeg, bmp, webp, pcx, tiff, tga, exif, svg, psd......那麼多。那麼在這麼多的格式中,你一定遇到過需要將格式轉成其他格式的情況吧!