摘自:http://blog.csdn.net/you_lan_hai/article/details/6770471
24位以上的位图文件包含3个部分:位图文件头(BITMAPFILEHEADER)、位图信息头(BITMAPINFOHEADER)、位图数据。
下面是MSDN中两个信息头的具体定义:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
   | typedef struct tagBITMAPFILEHEADER {    WORD    bfType; //图像类型:必须是‘BM’(BM的16进制编码为:0x4d42)   DWORD   bfSize; //文件大小。包含着两个结构,以及数据的总大小。
    WORD    bfReserved1; //保留值。必须为0   WORD    bfReserved2; //保留值。必须为0   DWORD   bfOffBits;   //从文件开头到数据的偏移量。也就是结构BITMAPFILEHEADER和结构BITMAPINFOHEADER的大小
  } BITMAPFILEHEADER, *PBITMAPFILEHEADER;  typedef struct tagBITMAPINFOHEADER{   DWORD  biSize; //当前结构体的大小。   LONG   biWidth; //位图的宽度。单位是像素   LONG   biHeight; //位图高度。单位是像素   WORD   biPlanes; //位图平面个数。必须是1   WORD   biBitCount //位图的位数,也就是位图深度。可以是1、4、8、16、24、32。16位以下的位图文件含有调色板信息。   DWORD  biCompression; //压缩方式。位图没有压缩,赋予BI_RGB参数(也就是0)。   DWORD  biSizeImage; //位图数据占用的字节数。可以设置为默认值0。   LONG   biXPelsPerMeter; //指定目标设备水平分辨率,单位是每米的像素个数。可设置为0   LONG   biYPelsPerMeter; //指定目标设备垂直分辨率,同上。   DWORD  biClrUsed; //指定本图像实际用到的像素。可设置为0   DWORD  biClrImportant; //指定本图像重要的颜色个数。可设置为0,表示所有颜色都重要。 } BITMAPINFOHEADER, *PBITMAPINFOHEADER; 
  | 
 
接下来就是位图数据了:
位图按行存贮,位图的宽度不等于位图的行字节数。每个像素占用 biBitCount/8 个字节,且每行占用的字节数必须是4字节的整数倍!例如:101*101*24的位图,行占用字节数为:101*3=303,而303%4!=0,所以行 占用字节数需修改为304,此时位图数据的实际大小为304*101,上面的biSizeImage就可设置为304*101。
下面是保存位图文件的结构体填充例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
   | BITMAPFILEHEADER bmheader;     memset(&bmheader,0,sizeof(bmheader));     bmheader.bfType=0x4d42;          bmheader.bfOffBits = sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER);      bmheader.bfSize = m_nWidthBytes*m_nHeight + bmheader.bfOffBits;
      BITMAPINFOHEADER bmInfo;     memset(&bmInfo,0,sizeof(bmInfo));     bmInfo.biSize = sizeof(bmInfo);     bmInfo.biWidth = m_nWidth;      bmInfo.biHeight = m_nHeight;      bmInfo.biPlanes = 1;      bmInfo.biBitCount =  m_nDeep;     bmInfo.biCompression = BI_RGB;
   | 
 
注:m_nWidthBytes 可这样计算:int m_nWidthBytes = ((m_nWidth*m_nDeep/8 + 3)/4) * 4;