C语言处理单色BMP文件
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
使用C处理单色BMP照片首先要了解BMP文件的格式:
BMP图片的扫描方式是从左到右,从下至上,对每个像素取值。一个扫描行所占的字节数为4的倍数,不足4的倍数系统自动扩展。
BMP文件包含一般包含4个部分(前三部分都是分开的结构体,是对数据的格式说明):
1、位图头文件(位图头文件包含的是整个文件的信息。
所有BMP文件的开始两个字节为0x424d,换为字符为BM,注
意输出BM的时候要以字符的形式一个一个的输出,如果以其
他格式,会使字符反向,这是源于内存中数据的存储方形成的。
位图头文件还包含整个文件的大小信息)
2、位图信息头(图像数据,即位图数据的格式与说明。)
3、颜色表(本文档只处理黑白文件,故不讨论颜色表)
4、位图数据(只包含图像的数据,格式包含于位图信
息头)
数据类型的定义:
WORD=unsigned short int 2byte
DWORD=unsigned int 4byte
LONG=int 4byte
位图头文件包含元素(结构体):14byte WORD bfType;//文件类型,其中的数据是0x424d,也就是BM DWORD bfSize;//整个文件的大小
WORD bfReserved1; //保留字未用
WORD bfReserved2; //保留字未用
DWORD bfOffBits;//位图数据与文件起始位置的字节偏移量,就是//位图与WORD bfType 中0x424d,‘42’的字节偏移量。
位图信息头(结构体):40byte DWORD biSize; //值为40
LONG biWidth; // 位图的宽度,以像素为单位
LONG biHeight; // 位图的高度,以像素为单位
WORD biPlanes; // 设备级别,值为1
WORD biBitCount;//每个像素所占的位数(bit),单色为1 DWORD biCompression; // 位图的压缩类型,0表示未压缩DWORD biSizeImage; //实际位图所占的字节数
LONG biXPelsPerMeter;
LONG biYPelsPerMeter;
DWORD biClrUsed;
DWORD biClrImportant;
头两个部分相加为54字节,故在内存一字节对齐(见内存对齐)的前提下,只需定义一个54字节的结构体就可以了。
颜色表(略)、位图数据(略)
不使用其他函数库(比如windows.h)来处理图片,而且我们还要知道图片的详细信息,那么我们就要获得BMP文件前两个部分的数据。
源代码:
#include
#include
#define WORD unsigned short int
#define DWORD unsigned int
#define LONG int
#pragma pack(1)//用于告诉编译器内存1字节对齐
//定义一个结构体,包含BMP文件前两个部分所有元素
structbmpheader//bmp header
{
WORD bfType;//value is BM
DWORD bfSize;//The total size of BMP file ,not just bit data(位图) WORD bfReserved1; //no
WORD bfReserved2; //no
DWORD bfOffBits; //bytes from begin to bit data
DWORD biSize;//value is 0x28
LONG biWidth;
LONG biHeight;
WORD biPlanes;//value is 1
WORD biBitCount;//the bits of every pixel needs
DWORD biCompression; //the way to compress
DWORD biSizeImage; //the bytes of bit data
LONG biXPelsPerMeter;
LONG biYPelsPerMeter;
DWORD biClrUsed;
DWORD biClrImportant;
}header;
main()
{
char *hd;//以字符的形式指向header的第一个字节
FILE *bmp;
if((bmp=fopen("****","rb"))==NULL)//****为文件名,后缀为bmp {
printf("Can't open this file!\n");
exit(0);
}//打开文件
hd=&header;//获得header的首地址赋予hd
fread(hd,1,54,bmp);//将所需的信息写入header结构体printf("文件类型:%c%c\n",hd[0],hd[1]);
printf("文件大小:%d byte\n",header.bfSize);
printf("位图字节偏移:%d\n",header.bfOffBits);
printf("位图信息头大小(值为40):%d\n",header.biSize);
printf("位图的宽度:%d\n",header.biWidth);
printf("位图的高度:%d\n",header.biHeight);
printf("设备的级别(值为1):%d\n",header.biPlanes);
printf("任一像素所占位数:%d bit\n",header.biBitCount);
printf("位图压缩类型:%d\n",header.biCompression);
printf("实际位图大小:%d byte\n",header.biSizeImage);
printf("显示设备水平分辨率:%f像素/米\n",header.biXPelsPerMeter);
printf("显示设备垂直分辨率:%f像素/米\n",header.biYPelsPerMeter);
system("pause");
}
上文只是获得了BMP文件的部分信息,但这是对BMP文件处理的关键所在。只要获得了文件的信息,余下的处理就简单多了。