例解BITMAP的数据格式

说明:由于这里不能上传bitmap图像,我将用到的3个bitmap图片(红色字体,第2、3两图是24bit的位图)文件放在:http://download.csdn.net/source/1377107。请下载(忘记设定不需要资源分了,需要1个资源分)后,对照本文阅读。

Bitmaps should be saved in a file that uses the established bitmap file format and assigned a name with the three-character .bmp extension. The established bitmap file format consists of a BITMAPFILEHEADER structure followed by a BITMAPINFOHEADER, BITMAPV4HEADER, or BITMAPV5HEADER structure. An array of RGBQUAD structures (also called a color table) follows the bitmap information header structure. The color table is followed by a second array of indexes into the color table (the actual bitmap data).

The bitmap file format is shown in the following illustration.

 

Windows 95, Windows NT 4.0: Replace the BITMAPINFOHEADER structure with the BITMAPV4HEADER structure.

Windows 98/Me, Windows 2000/XP: Replace the BITMAPINFOHEADER structure with the BITMAPV5HEADER structure.

The members of the BITMAPFILEHEADER structure identify the file; specify the size of the file, in bytes; and specify the offset from the first byte in the header to the first byte of bitmap data. The members of the BITMAPINFOHEADER, BITMAPV4HEADER, or BITMAPV5HEADER structure specify the width and height of the bitmap, in pixels; the color format (count of color planes and color bits-per-pixel) of the display device on which the bitmap was created; whether the bitmap data was compressed before storage and the type of compression used; the number of bytes of bitmap data; the resolution of the display device on which the bitmap was created; and the number of colors represented in the data. The RGBQUAD structures specify the RGB intensity values for each of the colors in the device's palette.

The color-index array associates a color, in the form of an index to an RGBQUAD structure, with each pixel in a bitmap. Thus, the number of bits in the color-index array equals the number of pixels times the number of bits needed to index the RGBQUAD structures. For example, an 8x8 black-and-white bitmap has a color-index array of 8 * 8 * 1 = 64 bits, because one bit is needed to index two colors. The Redbrick.bmp, mentioned in About Bitmaps, is a 32x32 bitmap with 16 colors; its color-index array is 32 * 32 * 4 = 4096 bits because four bits index 16 colors.

To create a color-index array for a top-down bitmap, start at the top line in the bitmap. The index of the RGBQUAD for the color of the left-most pixel is the first n bits in the color-index array (where n is the number of bits needed to indicate all of the RGBQUAD structures). The color of the next pixel to the right is the next n bits in the array, and so forth. After you reach the right-most pixel in the line, continue with the left-most pixel in the line below. Continue until you finish with the entire bitmap. If it is a bottom-up bitmap, start at the bottom line of the bitmap instead of the top line, still going from left to right, and continue to the top line of the bitmap.

The following hexadecimal output shows the contents of the file Redbrick.bmp.

 

第一图

The following table shows the data bytes associated with the structures in a bitmap file.

Structure

Corresponding bytes

BITMAPFILEHEADER

0x00 0x0D

BITMAPINFOHEADER

0x0E 0x35

RGBQUAD array

0x36 0x75

Color-index array

0x76 0x275


第一图的存储结构:

例解BITMAP的数据格式_第1张图片 

32 * 32 pixels (8 times enlarged redbrick.bmp) :

例解BITMAP的数据格式_第2张图片

Color table:

0   00 00 00 00

1   00 00 80 00

2   00 80 00 00

3   00 80 80 00

4   80 00 00 00

5   80 00 80 00

6   80 80 00 00

7   80 80 80 00

8      c0 c0 c0 00

9   00 00 ff 00

A   00 ff 00 00

B   00 ff ff 00

C   ff 00 00 00

D   ff 00 ff 00

E   ff ff 00 00

F   ff ff ff 00

 

The first three lines of Redbrick.bmp (bottom-up)

00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F

00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

00 00 00 00 00 00 00 00 09 00 00 00 00 00 00 00

11 11 01 19 11 01 10 10 09 09 01 09 11 11 01 90

 

From the above data, we can see the first line of the picture should be black (index 0 means black from  the color table), the second line is black except 18th pixels in line 2 is red (index 09 mean red from the color table). Obviously, we have the same result while look that enlarged redbrick.bmp above (bottom-up).

 

第2图 

  Englarged MSNFaceTest.bmp

   例解BITMAP的数据格式_第3张图片

第2图前128字节的数据如下:

00000000h   0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F

00000010h   42 4D 36 03 00 00 00 00 00 00 36 00 00 00 28 00

00000020h   00 00 10 00 00 00 10 00 00 00 01 00 18 00 00 00

00000030h   00 00 00 03 00 00 00 00 00 00 00 00 00 00 00 00

00000040h   00 00 00 00 00 00 22 19 15 23 1A 16 24 1B 17 24

00000050h   1C 15 22 1C 15 22 1C 15 1F 1C 14 25 24 1A 23 27

00000060h   1C 25 2B 20 28 32 26 28 37 29 27 38 2A 22 37 28

00000070h   1F 24 25 24 37 26 24 1E 19 21 1B 16 20 1A 15 21

00000080h   1B 14 22 1C 15 22 1C 15 1E 1C 14 1E 1F 15 23 29

 

  BITMAPFILEHEADER

  -----------------------

  WORD    bfType;        0x42 0x4D = BM

  DWORD   bfSize;        0x0336 = 822 bytes

  WORD    bfReserved1;   0x00   

  WORD    bfReserved2;   0x00   

  DWORD   bfOffBits;      0x36 = 54 bytes

 

  BITMAPINFOHEADER

  ------------------------

  DWORD  biSize;             0x28 = 40 bytes

  LONG   biWidth;            0x10 = 16 pixels

  LONG   biHeight;           0x10 = 16 pixels

  WORD   biPlanes;           0x01 = 1

  WORD   biBitCount;         0x18 = 24 bits-per-pixels

  DWORD  biCompression;      0x00

  DWORD  biSizeImage;        0x300 = 768 bytes

  LONG   biXPelsPerMeter;    0x00 = 0 pixels-per-meter

  LONG   biYPelsPerMeter;    0x00 = 0 pixels-per-meter

  DWORD  biClrUsed;         0x00

  DWORD  biClrImportant;     0x00

 

  RGBQUAD array (color table)

  ----------------------------

  NO COLOR TABLE

 

  BITMAP BITS (The first 2 pixels in the first line - bottom-up)

  --------------------------------------------------------------

  22 19 15  23 1A 16 (B-G-R)

 

第三图(MSNFaceTest01.bmp)

要注意的一点是在BMP位图中,位图的每行像素值要填充到一个四字节边界,即位图每行所占的存储长度为四字节的倍数,不足时将多余位用0填充

前面两图都刚好每一像素行都是4字节的倍数,因此没有碰到上面的情况。第一图是32 *32像素,每像素4-bit颜色值(在color table里面的indexcolor table的大小为16,即16种颜色),所以每行的字节数为32 *4 /8 = 16字节,显然为4的倍数,因此不需要补0;第二图是16*16像素,每像素为24 bits,因此每行的大小为 16 * 24 /8 = 48字节,显然也为4的倍数,故而也不存在补0的情况。下面给出一个需要补0的图形。

第3图

放大后的情形如下:

第3图的存储结构:

例解BITMAP的数据格式_第4张图片

  BITMAPFILEHEADER

  -----------------------

  WORD    bfType;        0x42 0x4D = BM

  DWORD   bfSize;        0x0196 = 406 bytes

  WORD    bfReserved1;   0x00   

  WORD    bfReserved2;   0x00   

  DWORD   bfOffBits;      0x36 = 54 bytes

 

  BITMAPINFOHEADER

  ------------------------

  DWORD  biSize;             0x28 = 40 bytes

  LONG   biWidth;            0x0E = 14 pixels

  LONG   biHeight;           0x08 = 8 pixels

  WORD   biPlanes;           0x01 = 1

  WORD   biBitCount;         0x18 = 24 bits-per-pixels

  DWORD  biCompression;      0x00

  DWORD  biSizeImage;        0x160 = 352 bytes

  LONG   biXPelsPerMeter;    0x00 = 0 pixels-per-meter

  LONG   biYPelsPerMeter;    0x00 = 0 pixels-per-meter

  DWORD  biClrUsed;         0x00

  DWORD  biClrImportant;     0x00

 

  RGBQUAD array (color table)

  ----------------------------

  NO COLOR TABLE

 

  BITMAP BITS

 

图像的尺寸为14*8像素,每个像素的颜色值占24bit,那么由此可以得到图像数据的大小应该为14 * 8 * 24/8 = 336字节,但是从从上面我们可以看到图像数据(BITMAP BYTES)的大小为352字节。两种算法所得的结果为什么会不同呢?这就要考虑到图像每行都必须是4字节的倍数,如果不是则要补0,知道这行图像数据为4的倍数。

 

在上面我们以及知道图像的宽度为14像素,每个像素的颜色值占25bit3字节,那么每行的字节数为14 * 3 = 42字节,不是4的倍数,那么就需要补2字节0,使每行为44字节,这样就变成了4的倍数,从而符合bmp的文件格式了。补0后的每行字节数为44,共有8行,因此图像数据的大小为44 * 8 = 352字节。这样就biSizeImage和一致了。

 

从上图中我们看到00000060h00000061h处补了2字节0(第一行),在0000008ch0000008dh处补了2字节0(第二行)

你可能感兴趣的:(C/C++)