解图像在计算机里的存储格式是进行图像处理的基础。在图像处理中最常见的处理对象即使无设备无关的位图。Windows 3.1 以上版本提供了对设备无关位图 DIB 的支持。DIB bbs.mnpub.net位图可以在不同的机器或系统中显示位图所固有的图像。DIB 是一种外部的位图格式,经常存储为以 BMP 为后缀的位图文件(有时也以 DIB 为后缀)。DIB 位图还支持图像数据的压缩。
DIB 是标准的 Windows 位图格式,BMP 文件包含了一个 DIB。一个 BMP 文件包括位图文件头结构BITMAPFILEHEADER、位图信息头结构BITMAPINFOHEADER、调色板 PALETTE 和位图像素数据 4个部分。
3.3.1 BITMAPFILEHEADER结构体
位图文件头结构体长度是固定的,为 14 个字节(WORD 为无符号 16 位整数,DWORD 为无符号 32 位整数),结构体定义如下:
typedef struct tagBITMAPFILEHEADER{
WORD bfType;
DWORD bfSize;
WORD bfReserved1;
WORD bfReserved2;
DWORD bfOffBits;
} BITMAPFILEHEADER, FAR *LPBITMAPFILEHEADER, *PBITMAPFILEHEADER;
这个结构各个域的说明如下:
bfType 指定文件类型,必须是 0x424D,即字符串“BM”,也就是说所有.bmp 文件的头两个字节都是“BM”。
bfSize 指定文件大小,包括这 14 个字节。
bfReserved1,bfReserved2 为保留字,不用考虑。
bfOffBits 为从文件头到实际的位图数据的偏移字节数,即图 1-7 中前三个部分的长度之和。
3.3.2 BITMAPINFOHEADER结构体
位图信息头结构体长度也是固定的,为40个字节。结构体定义下:
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;
这个结构各个域的说明如下:
biSize 指定这个结构的长度,为 40,单位是字节。
biWidth 指定图像的宽度,单位是像素。
biHeight 指定图像的高度,单位是像素。
biPlanes 为固定值,必须是 1。
biBitCount 指定表示颜色时要用到的位数,常用的值为 1(黑白二色图)、 4(16 色图)、8(256 色)、24(真彩色图)(新的.bmp 格式支持 32 位色,这里就不做讨论了)。
biCompression 指定位图是否压缩,有效的值为 BI_RGB,BI_RLE8,BI_RLE4,BI_BITFIELDS。
biSizeImage 指定实际的位图数据占用的字节数。如果 biCompression 为 BI_RGB,则该项可能为零。
biXPelsPerMeter 指定目标设备的水平分辨率,单位是每米的像素个数。
biYPelsPerMeter 指定目标设备的垂直分辨率,单位同上。
biClrUsed 指定本图像实际用到的颜色数,如果该值为零,则用到的颜色数为 2 的 biBitCount 次方。
biClrImportant 指定本图像中重要的颜色数,如果该值为零,则认为所有的颜色都是重要的。
3.3.3调色板
第三部分为调色板(Palette),当然,这里是对那些需要调色板的位图文件而言的。有些位图,如真彩色图是不需要调色板的,BITMAPINFOHEADER 后直接是位图数据。
现实世界的颜色种类是无限的,但计算机显示系统所能表现的颜色数量有限,因此,为了使计算机能最好地重现实际图景,就必须用一定的技术来管理和取舍颜色。 Windows提供了一个独立于硬件的颜色接口。程序提供了一个“绝对的”颜色码,Windows 把这个代码映射成计算机显示器上适当的颜色或颜色组合。
调色板实际上是一个数组,共有 biClrUsed 个元素(如果该值为零,则有 2 的 biBitCount 次方个元素)。数组中每个元素的类型是一个 RGBQUAD 结构,占 4 个字节,RGBQUAD 结构体定义如下:
typedef struct tagRGBQUAD {
BYTE rgbBlue;
BYTE rgbGreen;
BYTE rgbRed;
BYTE rgbReserved;
} RGBQUAD;
这个结构各个域的说明如下:
rgbBlue该颜色中蓝色分量。
rgbGreen该颜色数据中绿色分量。
rgbRed该颜色中红色分量。
rgbReserved保留值,无定义。
3.3.4象素矩阵数据
第四部分就是实际的图像数据了。对于用到调色板的位图,图像数据就是该像素值在调色板中的索引值,对于真彩色图,图像数据就是实际的 R、G、B 值。对于 2 色位图,用 1 位就可以表示该像素的颜色(一般 0 表示黑,1 表示白),所以一个字节可以表示 8 个像素。 对于 16 色位图,用 4 位可以表示一个像素的颜色,所以一个字节可以表示 2 个像素。对于 256 色位图,一个字节刚好可以表示 1 个像素。 对于真彩色图,三个字节才能表示 1 个像素。
需要注意的是每一行的字节数必须是 4 的整倍数,如果不是,则需要补齐。 在像素矩阵数据存储方式上,BMP 文件的数据从下到上,从左到右。也就是说,从文件中最先读到的是图像最下面一行的左边第一个像素,然后是左边第二个像素?接下来是倒数第二行左边第一个像素,左边第二个像素?依次类推 ,最后得到的是最上面一行的最右一个像素。