第三章:BMP文件的读取与显示
BMP文件的读取与显示
常见的图像文件格式
BMP(Bitmap位图)
是一种与设备无关(DIB)的图像文件格式,是Windows环境中经常使用的一种位图格式。其特点是不进行压缩,包含的图像信息丰富,但由此导致了占用磁盘空间过大的缺点。
BMP在单机上非常流行,不受Internet网络欢迎。
采用的是RGB色彩系统。
GIF(.gif)文件
GIF(Graphics Interchange Format)是美国联机服务商CompuServe针对当时网络传输带宽的限制开发的图像格式。其特点是压缩比高,磁盘空间占用较少,但不能存储超过256色的图像。
在Internet上广泛应用:
①它不仅可以存储单幅静止图像,也可以同时存储若干静止图像进而形成连续的动画;
②指定透明区域;
③渐显方式。
采用的是RGB色彩系统。
JPEG(.jpg)文件
JPEG(Joint Photographic Experts Group)是利用JPEG方法压缩的图像格式,有损压缩、压缩比非常高,但压缩/解压缩算法复杂、存储和显示速度慢。可以处理24位真彩色,适用于处理大幅的图像。
JPEG是Internet中 最受欢迎 的图像格式。
采用的是YCbCr色彩系统。
TIFF(.tif)文件
TIFF(Tag Image File Format)是一种独立于操作系统和文件系统的格式,便于在软件间进行图像数据交换。文件格式复杂,记录的相关信息多(图层、通道信息、多幅图像)。
该格式支持压缩;支持单色、256色、24位真彩色、32位色、48位色等多种色彩位;同时支持RGB、CMYK、YCbCr等多种色彩系统。
BMP图像文件结构
BITMAPFILEHEADER结构---14字节
1 |
|
这个结构的长度是固定的,为14个字节(WORD为无符号16位整数,DWORD为无符号32位整数),各个成员的说明如下:
bfType:文件类型,为BM,即0x4D42,表示BMP文件。
bfSize:文件大小,以字节为单位。
bfReserved1:保留字,为0。
bfReserved2:保留字,为0。
bfOffBits:图像数据相对于文件头的偏移量,即位图数据的起始位置。即结构示意图中前三个部分的长度之和。
BITMAPINFOHEADER结构---40字节
1 |
|
这个结构的长度是固定的,为40个字节,各个成员的说明如下:
biSize:指定结构大小,为40。
biWidth:指定图像的宽度,单位是像素。
biHeight:指定图像的高度,单位是像素。
biPlanes:必须是1,不用考虑。
biBitCount:指定表示颜色时要用到的位数,常用的值为1(黑白二色图), 4(16色图), 8(256色), 24(真彩色图)。
biBitCount在实验中会经常使用到!!!
biCompression 指定位图是否压缩。Windows位图可以采用压缩格式,但用的不多。我们只讨论的不压缩的情况,biCompression为BI_RGB(Windows定义好的常量) 。
biSizeImage 位图数据占用的字节数,可以通过图像的高度、宽度、颜色深度计算出来。如果biCompression为BI_RGB,则该项可以为零。
biXPelsPerMeter 指定目标设备的水平分辨率,单位是每米的像素个数。
biYPelsPerMeter 指定目标设备的垂直分辨率,单位同上。
biClrUsed 指定本图象实际用到的颜色数(决定调色板数组元素的个数),如果该值为零,则用到的颜色数为2的biBitCount次方。
biClrUsed在实验中也会经常使用到!!!
11。 biClrImportant 指定本图象中重要的颜色数,该值通常为零,即认为所有的颜色都是重要的。
Palette结构
调色板实际上是一个数组,共有biClrUsed个元素(如果该值为零,则有2的biBitCount次方个元素)。数组中每个元素的类型是一个RGBQUAD结构,占4个字节,其定义如下:
1
2
3
4
5
6typedef struct tagRGBQUAD {
BYTE rgbBlue; //该颜色的蓝色分量
BYTE rgbGreen; //该颜色的绿色分量
BYTE rgbRed; //该颜色的红色分量
BYTE rgbReserved; //保留值,不考虑
} RGBQUAD;
真彩色图,不需要调色板的,BITMAPINFOHEADER 后直接是位图数据
关于灰度图像的调色板
BMP格式的文件中并没有灰度图这个概念,但可以很容易地用BMP文件来表示灰度图。方法是用256色的调色板,不过这个调色板有些特殊,每一项的RGB都相同。RGB值从(0,0,0)、(1,1,1)一直到(255,255,255)。 (0,0,0)是全黑色, (255,255,255)是全白色。
对于R=G=B的色彩,带入HSI色彩系统转换公式中可以看到只有亮度信息,饱和度分量都是0,即没有色彩信息。
实际的位图数据 ImageData
对于用到调色板的位图,图象数据就是该像素颜色在调色板中的索引值,对于真彩色图,图像数据就是实际的R,G,B值。下面就2色,16色,256色位图和真彩色位图分别介绍
2色位图,用1位就可以表示该像素的颜色(一般0表示黑,1表示白),一个字节可以表示8个像素
16色位图,用4位可以表示一个像素的颜色,所以一个字节可以表示2个像素,分为前4位和后4位
256色位图,一个字节表示1个像素
真彩色图,三个字节表示1个像素,RGB分别占用一个字节
位图数据——需要注意的两点
① 每一行的字节数必须是4的整倍数,如果不是,则需要补齐。
② BMP文件的数据是从下到上,从左到右的。也就是说,从文件中最先读到的是图像最下面一行的左边第一个像素,然后是左边第二个像素。。。接下来是倒数第二行左边第一个像素,左边第二个像素。。。依次类推 ,最后得到的是最上面一行的最右一个像素。
这个指针2怎么得到的没搞懂
计算方法: 1
2
3
4int w = lpBitsInfo->bmiHeader.biWidth;
int h = lpBitsInfo->bmiHeader.biHeight;
int LineBytes = (w * lpBitsInfo->bmiHeader.biBitCount + 31) / 32 * 4;
BYTE* lpBits = (BYTE*)&lpBitsInfo->bmiColors[lpBitsInfo->bmiHeader.biClrUsed];
遍历灰度图像数据的方法: 1
2
3
4
5
6
7
8
9
10int i, j;
BYTE* pixel;
for (i = 0; i < h; i ++)
{
for (j = 0; j < w; j ++)
{
// 指向像素点(i,j)的指针
pixel = lpBits + LineBytes * (h - 1 - i) + j;
}
}