BMP文件组成 
BMP文件由文件头、位图信息头、颜色信息和图形数据四部分组成。 如图:

位图文件头BITMAPFILEHEADER
位图信息头BITMAPINFOHEADER
调色板Palette
实际的位图数据ImageDate

第一部

为位图文件头BITMAPFILEHEADER,是一个结构,其定义如下:

typedef struct tagBITMAPFILEHEADER {
WORD bfType;
DWORD bfSize;
WORD bfReserved1;
WORD bfReserved2;
DWORD bfOffBits;
} BITMAPFILEHEADER, *PBITMAPFILEHEADER;

bfType

指定文件类型,必须是0x424D,即字符串“BM”,也就是说所有.bmp文件的头两个字节都是“BM”。

bfSize
指定文件大小,包括这14个字节。
bfReserved1bfReserved2     
为保留字,不用考虑
bfOffBits
为从文件头到实际的位图数据的偏移字节数,即图中前三个部分的长度之和。
 
第二部分
为位图信息头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:指定结构体大小,按字节计算,不包括biClrUsed 成员提及的颜色表或掩码的大小。参见备注。

biWidth: 位图的宽度,按像素计算。

biHeight: 位图的高度,按像素计算。

如果biHeight为正数,位图为从下而上(bottom-up) DIB ,起点为左下角。

如果biHeight为负数,位图为从上而下(top-down) DIB ,起点为左上角,

如果biHeight为负数,标识一个从上而下(top-down) DIB,biCompression 必须为BI_RGB 或 BI_BITFIELDS。从上而下(top-down) DIB不能被压缩。

biPlanes:指定目标设备的planes的数量。 必须设定为 1 。

biBitCount:指定每个像素的位数。

该成员决定位图中定义每个像素的位数和最大颜色数量。 该成员必须为下面值中的一个:

描述

1

位图为黑白色,bmiColors 成员包含两个入口。位图数组中的每位代表一个像素。
如果该位被清除,像素被显示为bmiColors 表的第一个入口的颜色。
如果颜色被设置了,像素拥有bmiColors 表第二个入口的颜色。

2

位图有4个可能的颜色值。

4

位图有最大16位色,bmiColors 成员最多包含16个入口。

颜色表按照4位索引呈现位图中每个像素。例如,如果位图中的第一个字节是Ox1F,该字节代表2个像素。第一个像素包含第二个表入口的颜色,第二个像素包含第16个表入口的颜色。

8

位图最多有256中颜色,bmiColors 成员包含最多256个入口。这种情况下,数组中的每个字节代表单独一个像素。

16

位图最多有2^16 种颜色。

如果BITMAPINFOHEADER 的biCompression 成员值为BI_RGB , bmiColors 为NULL。位图数组中的每个字(WORD)代表单独一个像素。红、绿、蓝的相对强度分别以5位呈现。蓝色值为最低有效5位,接着5位是绿,然后是红。最高有效位不被使用。bmiColors 颜色表用来优化使用在基于调色板的设备上的颜色,而且必须包含BITMAPINFOHEADER的biClrUsed 成员指定的入口数量。

24

位图最多有2^24种颜色。bmiColors 为NULL。

位图数组中每个3字节三元组分别代表每个像素的蓝、绿、红色的相对强度。bmiColors 颜色表用来优化使用在基于调色板的设备上的颜色,而且必须包含BITMAPINFOHEADER的biClrUsed 成员指定的入口数量。

32

位图最多有2^32种颜色。

如果BITMAPINFOHEADER 的biCompression 成员是BI_RGB , bmiColors 为NULL。位图数组中的每个双字(DWORD)分别代表每个像素的蓝、绿、红色的相对强度。每个双字的高字节不使用。bmiColors 颜色表用来优化使用在基于调色板的设备上的颜色,而且必须包含BITMAPINFOHEADER的biClrUsed 成员指定的入口数量。

如果BITMAPINFOHEADER 的biCompression 的值为BI_BITFIELDS,bmiColors 成员包含3个双字颜色掩码来分别指定组成每个像素的红、绿、蓝色。

位图数组中的每个双字代表一个像素。

biCompression:为压缩的bottom-up位图指定压缩类型,而top-down DIBs 不能被压缩。该成员值可能为下表中的一个:

描述

BI_RGB

未压缩的格式

BI_BITFIELDS

用来说明位图没有被压缩并且颜色表由3个双字颜色掩码组成(3个双字颜色掩码来分别指定组成每个像素的红、绿、蓝值)。

当使用16bpp和32bpp位图时该标志可用。

该值在Windows CE 2.0 及其以后版本可用。

BI_ALPHABITFIELDS

用来说明位图没有被压缩并且颜色表由4个双字颜色掩码组成(4个双字颜色掩码来分别指定组成每个像素的红、绿、蓝和alpha值)。

当使用16bpp和32bpp位图时该标志可用。

该值在Windows CE 4.0 及其以后版本可用。

对于Windows CE 5.0 及其以后版本,可有使用上表的任意值与BI_SRCPREROTATE 进行布尔OR 运算来标明源DIB和目的DIB有相同的旋转角度。

biSizeImage:指定图像的大小,按字节计算。当为BI_RGB 时,该值可以设置为0。

biXPelsPerMeter:为位图指定目标设备水平分辨率,按每公尺像素数计算(in pixels per meter)。程序使用该值从资源组中选择最符合当前设备特性的位图。

biYPelsPerMeter:为位图指定目标设备垂直分辨率按每公尺像素数计算(in pixels per meter)。

biClrUsed:指定实际在位图中使用的颜色表中的颜色索引的数量。

如果该值为0,位图为biCompression 指定的压缩模式使用biBitCount 值对应的最大颜色数量。
    如果biClrUsed 非0,并且biBitCount 小于16,biClrUsed 指定图形引擎或设备驱动访问的实际颜色数量。
    如果biBitCount 大于等于16,biClrUsed 指定颜色表的数量,用来优化系统颜色调色板性能。
    如果biBitCount 等于16或32,最佳颜色调色板紧跟在3个双字掩码之后开始(the optimal color palette starts immediately following the three DWORD masks.)。
    如果位图被封装了(位图数组紧接着BITMAPINFO头,并被一个单独指针引用),biClrUsed 必须要么为0,要么为颜色表的实际大小。

biClrImportant:显示位图时指的定颜色索引的数量。如果该值为0,要求使用所有颜色。

备注:

   BITMAPINFO 结构合并BITMAPINFOHEADER和一个颜色表来提供对一个DIB的尺寸大小和颜色的完全定义。程序应该使用存储在biSize 中的信息来定位BITMAPINFO 结构中的颜色表,如下,

pColor = ((LPSTR)pBitmapInfo + (WORD)(pBitmapInfo->bmiHeader.biSize));

对于Windows CE 1.0 和1.01版本,biBitCount 必须为1或2.

 

第三部分

为调色板Palette,当然,这里是对那些需要调色板的位图文件而言的。有些位图,如真彩色图,前面已经讲过,是不需要调色板的,BITMAPINFOHEADER后直接是位图数据。

调色板实际上是一个数组,共有biClrUsed个元素(如果该值为零,则有2biBitCount个元素)。数组中每个元素的类型是一个RGBQUAD结构,占4个字节,其定义如下:
typedef struct tagRGBQUAD {
BYTE rgbBlue; //该颜色的蓝色分量
BYTE rgbGreen; //该颜色的绿色分量
BYTE rgbRed; //该颜色的红色分量
BYTE rgbReserved; //保留值
} RGBQUAD;

第四部分

位图数据记录了位图的每一个像素值,记录顺序是在扫描行内是从左到右,扫描行之间是从下到上。对于用到调色板的位图,图象数据就是该象素颜在调色板中的索引值。对于真彩色图,图象数据就是实际的R、G、B值。下面针对2色、16色、256色位图和真彩色位图分别介绍。

对于2色位图,用1位就可以表示该象素的颜色(一般0表示黑,1表示白),所以一个字节可以表示8个象素。

对于16色位图,用4位可以表示一个象素的颜色,所以一个字节可以表示2个象素。
对于256色位图,一个字节刚好可以表示1个象素。
对于真彩色图,三个字节才能表示1个象素,哇,好费空间呀!没办法,谁叫你想让图的颜色显得更亮丽呢,有得必有失嘛。
要注意两点:
(1)    每一行的字节数必须是4的整倍数,如果不是,则需要补齐。这在前面介绍biSizeImage时已经提到了。
(2)    一般来说,.bMP文件的数据从下到上,从左到右的。也就是说,从文件中最先读到的是图象最下面一行的左边第一个象素,然后是左边第二个象素……接下来是倒数第二行左边第一个象素,左边第二个象素……依次类推 ,最后得到的是最上面一行的最右一个象素。
 

Windows GDI定义了将信息头颜色表组合在一起的数据结构 BITMAPINFO

typedef struct tagBITMAPINFO {
    BITMAPINFOHEADER  bmiHeader;
    RGBQUAD           bmiColors[1];
} BITMAPINFO;

成员:

bmiHeader: 位图信息头结构,该结构包含了位图的尺寸和颜色格式。

bmiColors: 包含下面中的一种。

  • RGBQUAD 数组。数组元素填充颜色表。
  • 16位无符号整形数组,该数组指定索引到当前已实现的逻辑调色板。

    允许在使用DIB的函数中使用bmiColors 。当bmiColors 包含已实现的逻辑调色板的索引时,必须也要调用CreateDIBPatternBrushPt CreateDIBSection CreateDIBSection iUsage 成员必须被设置为DIB_PAL_COLORS

    BITMAPINFOHEADER 结构的biBitCount biClrUsed 成员的值决定数组的大小。

    bmiColors 表中的颜色根据重要性排序。更多信息,参见备注。

  • 如果bmiHeader.biCompression 被设置为BI_RGB ,可以设置bmiColors 数组大小为0.

备注:

设备独立位图由2部分组成:用于描述位图的尺寸大小和颜色的BITMAPINFO 结构和定义位图像素的字节数组。字节数组中的所有位封装在一起,但每行扫描必须在行尾补0以确保行尾为LONG数据类型边界(each scan line must be padded with zeroes to end on a LONG data-type
boundary.
)。

如果位图高度为正数,则位图为从下到上(bottom-up)DIB,它的起点为左下角坐标。如果高度为负数,则位图为从上到下(top-down) DIB,它的起点为左上角。

封装位图时,位图字节数组紧跟在BITMAPINFO 头后面。封装的位图被一个单独指针引用。

对于封装的位图,当使用DIB_PAL_COLORS模式时,BITMAPINFOHEADER 结构的ClrUsed 成员必须设置为偶数,因此,DIB位图数组以DWORD边界开始。

如果位图被存储至文件或传送到其他应用程序,bmiColors 成员不应包含调色板索引。

除非程序独占使用和控制位图,否则位图颜色表应该包含明确的RGB值。

安全提示: 一个常见的错误类型包括在内容中发现无效的格式描述。比如,一个BITMAPINFOHEADER 结构后跟着一个颜色表。

   BITMAPINFO 结构被定义为一个BITMAPINFOHEADER 结构后跟着一个填充颜色表RGBQUAD 数组。RGBQUAD 数组大小由BITMAPINFOHEADER 中的biClrUsed值决定。

在拷贝颜色表到BITMAPINFO前一定要检查为BITMAPINFO结构分配的缓冲大小,否则决不能那么做。

Windows GDI定义了将设备无关的位图(DIB)颜色表组合在一起的数据结构 BITMAPCOREINFO。

typedef struct _BITMAPCOREINFO {
BITMAPCOREHEADER bmciHeader; //指定一个BITMAPCOREHEADER结构,它包含一个DIB的尺寸和颜色格式的信息
RGBTRIPLE bmciColors[1]; //RGBTRIPLE数组定义的位图中的颜色
} BITMAPCOREINFO, *PBITMAPCOREINFO;

  

BMP文件组成的更多相关文章

  1. Matlab 读取文件夹中所有的bmp文件

    将srcimg文件下的bmp文件转为jpg图像,存放在dstimg文件夹下 str = 'srcimg'; dst = 'dstimg'; file=dir([str,'\*.bmp']); :len ...

  2. 图像预处理第9步:存为.bmp文件

    //图像预处理第9步:将最终标准化后的字符图像分为单个单个的HDIB保存,并存为.bmp文件 void CChildView::OnImgprcToDibAndSave() { unsigned ch ...

  3. Bitmap文件格式+生成一个BMP文件

    Bitmap的文件格式: #define UINT16 unsigned short #define DWORD unsigned int #define WORD short #define LON ...

  4. [代码片段]读取BMP文件

    文件名mybmp.c //实现了读取24位BMP文件,还有一些测试信息 //定义mybmp.c里面用到的函数和相关头文件.常量 //参考了网友sailinghz在CSDN论坛的帖子:http://bb ...

  5. 将HDC保存为BMP文件

    HDC在MSDN中的全称为:The handle of device context.通常,我们都是用来做相应的显示操作.        熟悉WIN32的朋友对于其应该不会陌生,经常采用GetDC,G ...

  6. 数据恢复培训资料:BMP文件详解

    BMP是一种与硬件设备无关的图像文件格式,使用非常广.它采用位映射存储格式,除了图像深度可选以外,不采用其他任何压缩,因此,BblP文件所占用的空间很大.BMP文件的图像深度可选lbit.4bit.8 ...

  7. BMP文件解析

    目录 BMP文件简介 BMP文件格式 位图头 位图信息 调色板 位图数据 C语言代码 获取文件大小 获取文件尺寸 获取文件偏移量 读取文件数据示例 一个问题 完整程序 BMP文件简介 BMP(全称Bi ...

  8. oracle windows 新建用户授权 导出导入bmp文件

    1.新建用户 sqlplus /no log conn /as sysdba create user tkjj identified by tkjj2017 grant dba to tkjj con ...

  9. BMP文件解析【转】

    本文转载自:http://blog.csdn.net/Blues1021/article/details/44954817 BMP文件通常是不压缩的,所以它们通常比同一幅图像的压缩图像文件格式要大很多 ...

随机推荐

  1. lock关键字的使用

    最近在代码中,发现别人使用了lock关键字,为了理解别人写的代码,所以自己对lock关键字的使用研究了下. 微软官方解释,请百度:lock 语句(C# 参考) 微软给了个官网实例代码: class A ...

  2. C#-WinForm控制输入框只接受数字输入

    背景 给导师上一节c#编写数据库应用程序的课,模拟ATM自助取款机的功能写了个winForm程序,关于金额的输入肯定是数字,因此避免输入格式不正确的数字带来异常,直接在输入时进行校验. 封装函数 C# ...

  3. 【bzoj1061】[NOI2008]志愿者招募 线性规划与费用流

    题目描述 申奥成功后,布布经过不懈努力,终于成为奥组委下属公司人力资源部门的主管.布布刚上任就遇到了一个难题:为即将启动的奥运新项目招募一批短期志愿者.经过估算,这个项目需要N 天才能完成,其中第i ...

  4. hdu6121 build a tree(树)

    题解: 可以考虑每一层结点的子树大小 必定满足下面的情况,即 a,a,a,a,a,a,b,c,c,c,c........ 然后每一层依次往上更新,结果是不变的 一共有logn层,所以依次扫上去,统计结 ...

  5. visio中相关设置-菜单视图

    1.获取或设置窗口中页面的当前显示大小(缩放系数) Window.Zoom Dim dZoom As Double dZoom = m_Visio.Window.Zoom'获取显示比例 m_Visio ...

  6. WIN7服务优化,别关太多,小心启动不

    原文链接地址:http://blog.csdn.net/civilman/article/details/51423972 Adaptive brightness 监视周围的光线状况来调节屏幕明暗,如 ...

  7. CF451E Devu and Flowers 解题报告

    CF451E Devu and Flowers 题意: \(Devu\)有\(N\)个盒子,第\(i\)个盒子中有\(c_i\)枝花.同一个盒子内的花颜色相同,不同盒子的花颜色不同.\(Devu\)要 ...

  8. Hadoop 学习之MapReduce

    MapReduce充分利用了分而治之,主要就是将一个数据量比较大的作业拆分为多个小作业的框架,而用户需要做的就是决定拆成多少份,以及定义作业本身,用户所要做的操作少了又少,真是Very Good! 一 ...

  9. hdu 1520Anniversary party 树形dp入门

    There is going to be a party to celebrate the 80-th Anniversary of the Ural State University. The Un ...

  10. 使用记事本创建Web服务(WebService)

    学习就要从最简单最直观的地方入手. 1)打开记事本,添加如下代码: <%@ WebService Language="C#" Class="myFirstWebSe ...