图像处理资料
(位图的读取、处理相关算法精解)
间
时
2013.04.17
:
位图格式:
BMP 文件可分为四个部分:位图文件头、位图信息头、彩色板、图像数据阵列。
一:位图文件头的格式:
typedef struct{
int bfType;//bfType(2 字节),这里恒定等于&H4D42,ASCII 字符‘BM’
long bfSize;//文件大小,以 4 字节为单位
int bfReserve1;//备用
2 个字节
int bfReserve2;//备用
2 个字节
long bfoffBits;//数据区在文件中的位置偏移量 4 字节
}BITMAPFILEHEADER;//文件头结构体,14 字节
BITMAPFILEHEADER 只占了 bmp 文件开始的 14 字节长度,但需要 特别说明的是在
vb 中定义一个 BITMAPFILEHEADER 结构体变量,其长度占了 16 个字节,原因就是第 1 个属性
本来应该只分配 2 个字节,但实际被 分配了 4 个字节,多出来 2 个字节,所以如果想保存一张 bmp
图片,写入 BITMAPFILEHEADER 结构体时一定要注意这一点。
二:位图信息头
typedef struct{
long bitSize;//位图信息头大小
long biWidth;//图象宽度,像素单位
long biHeight;//图象高度,像素单位
int biPlanes;//位平面树=1
int biBitCount;//单位像素的位数,表示 bmp 图片的颜色位数,即 24 位图、32 位图
long biCompression;//图片的压缩属性,bmp 图片是不压缩的,等于 0
long biSizeImage;表示 bmp 图片数据区的大小,当上一个属性 biCompression 等于 0 时,这里的
值可以省略不填
long biXPlosPerMeter;//水平分辨率,可省略
long biYPlosPerMeter;//垂直分辨率,可省略
long biClrUsed;//表示使用了多少个颜色索引表,一般 biBitCount 属性小于 16 才会用到,等于 0
时表示有 2^biBitCount 个颜色索引表
long biClrImportant;//表示有多少个重要的颜色,等于 0 时表示所有颜色都很重要
}BITMAPINFOHEADER;//位图信息头,40 字节
BITMAPINFOHEADER 的第 1 个属性是 biSize(4 字节),表示 BITMAPINFOHEADER 结构体的
长度,最常见的长度是 40 字节,UltraEdit 中可以看到紧接着的 4 个字节等于&H00000028=40
字节。
BITMAPINFOHEADER 的第 2 个属性是 biWidth(4 字节),表示 bmp 图片的宽度,这里等于
&H00000030=48 像素。
BITMAPINFOHEADER 的第 3 个属性是 biHeight(4 字节),表示 bmp 图片的高度,这里等于
&H00000030=48 像素。
BITMAPINFOHEADER 的第 4 个属性是 biPlanes(2 字节),表示 bmp 图片的平面属,显然显示器
只有一个平面,所以恒等于 1,这里等于&H0001。
BITMAPINFOHEADER 的第 5 个属性是 biBitCount(2 字节),表示 bmp 图片的颜色位数,即 24
位图、32 位图等等。这里等于&H0004,表示该图片为 4 位图。
BITMAPINFOHEADER 的第 6 个属性是 biCompression(4 字节),表示图片的压缩属性,bmp 图
片是不压缩的,等于 0,所以这里为&H00000000。
BITMAPINFOHEADER 的第 7 个属性是 biSizeImage(4 字节),表示 bmp 图片数据区的大小,当
上一个熟悉 biCompression 等于 0 时,这里的值可以省略不填,所以这里等于&H00000000。
BITMAPINFOHEADER 的第 8 个属性是 biXPelsPerMeter(4 字节),表示图片 X 轴每米多少像素,
可省略,这里等于&H00000EC3=3779 像素/米。
BITMAPINFOHEADER 的第 9 个属性是 biYPelsPerMeter(4 字节),表示图片 Y 轴每米多少像素,
可省略,这里等于&H00000EC3=3779 像素/米。
BITMAPINFOHEADER 的第 10 个属性是 biClrUsed(4 字节),表示使用了多少个颜色索引表,一
般 biBitCount 属性小于 16 才会用到,等于 0 时表示有 2^biBitCount 个颜色索引表,所以这里仍
等于&H00000000。
BITMAPINFOHEADER 的第 11 个属性是 biClrImportant(4 字节),表示有多少个重要的颜色,
等于 0 时表示所有颜色都很重要,所以这里等于&H00000000。
RGBQUAD 结构体由 4 个字节型数据组成,所以一 个 RGBQUAD 结构体只占用 4 字节空间,从左
到右每个字节依次表示(蓝色,绿色,红色,未使用)。
typedef struct tagRGBQUAD {
BYTErgbBlue;// 蓝色的亮度(值范围为 0-255)
BYTErgbGreen; // 绿色的亮度(值范围为 0-255)
BYTErgbRed; // 红色的亮度(值范围为 0-255)
BYTErgbReserved;// 保留,必须为 0
} RGBQUAD;
位图数据的读取程序一
#include
#include
#include
#include
#include
#define WIDTHBYTES(bits) (((bits)+31)/32*4)
typedef unsigned char BYTE;
typedef unsigned short WORD;
typedef unsigned long DWORD;
typedef long LONG;
//位图文件头信息结构定义
//其中不包含文件类型信息(由于结构体的内存结构决定,要是加了的话将不能正确读取文件信息)
typedef struct tagBITMAPFILEHEADER {
DWORD bfSize;
//文件大小
WORD bfReserved1;
//保留字,不考虑
WORD bfReserved2;
//保留字,同上
DWORD bfOffBits;
//实际位图数据的偏移字节数,即前三个部分长度之和
} BITMAPFILEHEADER;
//信息头 BITMAPINFOHEADER,也是一个结构,其定义如下:
typedef struct tagBITMAPINFOHEADER{
//public:
DWORD biSize;
//指定此结构体的长度,为 40
LONG
biWidth;
LONG
biHeight;
//位图宽
//位图高
WORD
biPlanes;
//平面数,为 1
WORD
biBitCount;
//采用颜色位数,可以是 1,2,4,8,16,24,新的可以是
32
DWORD biCompression;
//压缩方式,可以是 0,1,2,其中 0 表示不压缩
DWORD biSizeImage;
//实际位图数据占用的字节数
LONG
biXPelsPerMeter;
//X 方向分辨率
LONG
biYPelsPerMeter;
//Y 方向分辨率
DWORD biClrUsed;
//使用的颜色数,如果为 0,则表示默认值(2^颜色位数)
DWORD biClrImportant;
//重要颜色数,如果为 0,则表示所有颜色都是重要的
} BITMAPINFOHEADER;
//调色板 Palette,当然,这里是对那些需要调色板的位图文件而言的。24 位和 32 位是不需要调色
板的。
//(似乎是调色板结构体个数等于使用的颜色数。)
typedef struct tagRGBQUAD {
//public:
BYTE
rgbBlue; //该颜色的蓝色分量
BYTE
rgbGreen; //该颜色的绿色分量
BYTE
rgbRed; //该颜色的红色分量
BYTE
rgbReserved; //保留值
} RGBQUAD;
void showBmpHead(BITMAPFILEHEADER* pBmpHead)
{
printf("位图文件头:\n");
printf("文件大小:%d\n",pBmpHead->bfSize);
printf("保留字:%d\n",pBmpHead->bfReserved1);
printf("保留字:%d\n",pBmpHead->bfReserved2);
printf("实际位图数据的偏移字节数:%d\n",pBmpHead->bfOffBits);
}
void showBmpInforHead(tagBITMAPINFOHEADER* pBmpInforHead)
{
printf("位图信息头:\n");
printf("结构体的长度:%d\n",pBmpInforHead->biSize);
printf("位图宽:%d\n",pBmpInforHead->biWidth);
printf("位图高:%d\n",pBmpInforHead->biHeight);
printf("biPlanes 平面数:%d\n",pBmpInforHead->biPlanes);
printf("biBitCount 采用颜色位数:%d\n",pBmpInforHead->biBitCount);
printf("压缩方式:%d\n",pBmpInforHead->biCompression);
printf("biSizeImage 实际位图数据占用的字节数:%d\n",pBmpInforHead->biSizeImage);
printf("X 方向分辨率:%d\n",pBmpInforHead->biXPelsPerMeter);
printf("Y 方向分辨率:%d\n",pBmpInforHead->biYPelsPerMeter);
printf("使用的颜色数:%d\n",pBmpInforHead->biClrUsed);
printf("重要颜色数:%d\n",pBmpInforHead->biClrImportant);
}
void showRgbQuan(tagRGBQUAD* pRGB)
{
printf("(%-3d,%-3d,%-3d)
",pRGB->rgbRed,pRGB->rgbGreen,pRGB->rgbBlue);