Bmp格式,关于BITMAPFILEHEADER 和 BITMAPINFOHEADER 不说了,网络上全都有。
从0x36字节开始说起,根据bmp不同的格式,内容有所不同:
先谈谈8bit Bitmap (Monochrome Bitmap),建议使用像素1*1的文件进行分析。8bit文件只有两种颜色:白或者黑。需要定义彩色表,结构就是RGBQUAD。 因为黑白两种,所以从0x36开始需要 2 * 4 bytes,1个RGBGUAD的大小是4。 数据分别为:
00000000( 数值:0x00000000) 黑色
FFFFFF00( 数值:0x00FFFFFF) 白色
因为数据小端排列
0x3E开始是真正的数据,该数据必须是4的整数倍。
如果这个像素的点是黑色,二进制00000000, 最高位为0。索引0x36的第一个值-->0x00000000
如果这个像素的点是黑色,二进制80000000, 最高位为1。索引0x36的第二个值-->0x00FFFFFF
如果定义像素是1*2, 最高两位有4种选择: 00000000, 80000000, C0000000, 40000000。
如果设置像素是1*3, 就会变更最高的3位
所以一个整形最大允许32个像素1*32。
但是注意高度只能为1。如果像素是2*1,数据是8,而不仅仅是4。
同理对于16bit Bitmap 和 256bit Bitmap. 只是16bit RGBQUAD有16个索引,从0x36 - 0x46. 256bit就更加多了,一共256个索引。
对于24bit Bitmap,格式不一样,没有RGBQUAD。具体定义再说。
参考: http://www.blogjava.net/georgehill/articles/6549.html
0022h 字节数表示的位图数据的大小。该数必须是4的倍数
表示真正的像素大小,必须为4的整数倍。我们讨论像素1*1, 1*2, 1*3 and 1*4这四种case,表示一行有一个点,两个点,三个点和四个点。BMP格式是24bit真彩色。
1*1 (0x22的值:0400 0000)从 0x36开始,占用四个字节,如果颜色是白色,数值是 FFFF FF00,最后00仅仅是填充作用,占用4个字节。白色就是0xFFFFFF。
1*2 (0x22的值:0800 0000)从 0x36开始,占用八个字节,如果颜色是白色,数值是 FFFF FFFF FFFF 0000,最后4个0仅仅是填充作用,占用8字节。FF有两个白色。
1*3 (0x22的值:0C00 0000)从 0x36开始,占用12字节,如果颜色是白色,数值是 FFFF FFFF FFFF FFFF FF00 0000,最后6个0仅仅是填充作用,占用12字节。FF有三个白色。
1*4 (0x22的值:0C00 0000)从 0x36开始,占用12字节,如果颜色是白色,数值是 FFFF FFFF FFFF FFFF FFFF FFFF,12个字节正好全部填满,不需要填充。
所以1*3 和 1*4 在0x22h处的大小都是0xC。