logo资料库

使用C语言读取位图.docx

第1页 / 共11页
第2页 / 共11页
第3页 / 共11页
第4页 / 共11页
第5页 / 共11页
第6页 / 共11页
第7页 / 共11页
第8页 / 共11页
资料共11页,剩余部分请下载后查看
使用C语言读取位图  
使用 C 语言读取位图 2010-09-16 16:04:43| 分类: C 语言 | 标签:c 语言处理位图 |字号 订阅 一、位图文件结构 位图文件由三部分组成:文件头 + 位图信息 + 位图像素数据 1、位图文件头。位图文件头主要用于识别位图文件。以下是位图文件头结构的定义: typedef struct tagBITMAPFILEHEADER { // bmfh WORD bfType; DWORD bfSize; WORD WORD bfReserved1; bfReserved2; DWORD bfOffBits; } BITMAPFILEHEADER; 其中的 bfType 值应该是“BM”(0x4d42),标志该文件是位图文件。bfSize 的值是位图文件 的大小。 2、位图信息中所记录的值用于分配内存,设置调色板信息,读取像素值等。 以下是位图信息结构的定义: typedef struct tagBITMAPINFO { BITMAPINFOHEADER bmiHeader; RGBQUAD bmiColors[1]; } BITMAPINFO; 可见位图信息也是由两部分组成的:位图信息头 + 颜色表 2.1 位图信息头。位图信息头包含了单个像素所用字节数以及描述颜色的格式,此外还包括 位图的宽度、高度、目标设备的位平面数、图像的压缩格式。以下是位图信息头结构的定义: typedef struct tagBITMAPINFOHEADER{ // bmih DWORD biSize; LONG LONG WORD WORD biWidth; biHeight; biPlanes; biBitCount DWORD biCompression; DWORD biSizeImage; LONG LONG biXPelsPerMeter; biYPelsPerMeter; DWORD biClrUsed;
DWORD biClrImportant; } BITMAPINFOHEADER; 下表是对结构体当中各个成员的说明: 结构成员 biSize biWidth biHeight biplanes 结构 BITMAPINFOHEADER 的字节数,即 sizeof(BITMAPINFOHEADER)* 说 明 以像素为单位的图像宽度* 以像素为单位的图像长度* 目标设备的位平面数 biBitCount 每个像素的位数*(1) biCompression 图像的压缩格式(这个值几乎总是为 0) biSizeImage 以字节为单位的图像数据的大小(对 BI_RGB 压缩方式而言) biXPelsPermeter 水平方向上的每米的像素个数 biYpelsPerMeter 垂直方向上的每米的像素个数 biClrused 调色板中实际使用的颜色数(2) biClrImportant 现实位图时必须的颜色数(3) 说明:*是需要加以注意的部分,因为它们是我们在进行位图操作时经常参考的变量 (1)对于每个像素的字节数,分别有一下意义: 0,用在 JPEG 格式中 1,单色图,调色板中含有两种颜色,也就是我们通常说的黑白图片 4,16 色图 8,256 色图,通常说的灰度图 16,64K 图,一般没有调色板,图像数据中每两个字节表示一个像素,5 个或 6 个位表示一 个 RGB 分量 24,16M 真彩色图,一般没有调色板,图像数据中每 3 个字节表示一个像素,每个字节表 示一个 RGB 分量 32,4G 真彩色,一般没有调色板,每 4 个字节表示一个像素,相对 24 位真彩图而言,加 入了一个透明度,即 RGBA 模式 (2)这个值通常为 0,表示使用 biBitCount 确定的全部颜色,例外是使用的颜色树木小于 制定的颜色深度的颜色数目的最大值。 (3)这个值通常为 0,表示所有的颜色都是必需的 2.2 颜色表。颜色表一般是针对 16 位一下的图像而设置的,对于 16 位和 16 位以上的图像, 由于其位图像素数据中直接对对应像素的 RGB(A)颜色进行描述,因而省却了调色板。而对 于 16 位一下的图像,由于其位图像素数据中记录的只是调色板索引值,因而需要根据这个 索引到调色板去取得相应的 RGB(A)颜色。颜色表的作用就是创建调色板。
颜色表是由颜色表项组成的,颜色表项结构的定义如下: typedef struct tagRGBQUAD { // rgbq BYTE BYTE BYTE BYTE rgbBlue; rgbGreen; rgbRed; rgbReserved; } RGBQUAD; 其中需要注意的问题是,RGBQUAD 结构中的颜色顺序是 BGR,而不是平常的 RGB。 3、位图数据。最后,在位图文件头、位图信息头、位图颜色表之后,便是位图的主体部分: 位图数据。根据不同的位图,位图数据所占据的字节数也是不同的,比如,对于 8 位位图, 每个字节代表了一个像素,对于 16 位位图,每两个字节代表了一个像素,对于 24 位位图, 每三个字节代表了一个像素,对于 32 位位图,每四个字节代表了一个像素。 下面附上代码: // Bmp.cpp : 定义控制台应用程序的入口点。 // #include "stdafx.h" int _tmain(int argc, _TCHAR* argv[]) { int ReadFileHeader(char *filepath,BITMAPFILEHEADER *bmfh); int ReadInfoHeader(char *filepaht,BITMAPINFOHEADER *bmih); int ReadPixelData(char *filepath); DWORD GetLineBytes(int width,int bitCount); //BYTE *imgData; //int i=ReadPixelData("E:\\1\\1.bmp"); int i=ReadPixelData("D:\\2.bmp"); scanf("%d"); return 0; } //读入文件头 int ReadFileHeader(char *filepath,BITMAPFILEHEADER *bmfh) { FILE *fp;
//打开文件 fp=fopen(filepath,"rb"); if(!fp) { //如果打开失败 printf("Can not open the file:%s\n",filepath); return -1; } //读入 bfType if(fread(&bmfh->bfType,sizeof(WORD),1,fp)!=1) { printf("Can not read bfType in the file header.\n"); fclose(fp); return -1; } //读入 bfSize if(fread(&bmfh->bfSize,sizeof(DWORD),1,fp)!=1) { printf("Can not read bfSize in the file header.\n"); fclose(fp); return -1; } //读入 bfReserved1 if(fread(&bmfh->bfReserved1,sizeof(WORD),1,fp)!=1) { printf("Can not read bfReserved1 in the file header.\n"); fclose(fp); return -1; } //读入 bfReserved2 if(fread(&bmfh->bfReserved2,sizeof(WORD),1,fp)!=1) { printf("Can not read bfReserved2 in the file header.\n"); fclose(fp); return -1; } //读入 bfOffBits if(fread(&bmfh->bfOffBits,sizeof(DWORD),1,fp)!=1) {
printf("Can not read bfOffBits in the file header.\n"); fclose(fp); return -1; } //关闭文件指针 fclose(fp); return 0; } //读入信息头 int ReadInfoHeader(char *filepath,BITMAPINFOHEADER *bmih) { FILE *fp; //打开文件 fp=fopen(filepath,"rb"); if(!fp) { printf("Can not open the file:%s\n",filepath); return -1; } //使文件指针跳过文件头(14 字节) fseek(fp,14,SEEK_SET); //读入 biSize if(fread(&bmih->biSize,sizeof(DWORD),1,fp)!=1) { printf("Can not read biSize in the info header.\n"); fclose(fp); return -1; } //读入 biWidth if(fread(&bmih->biWidth,sizeof(LONG),1,fp)!=1) { printf("Can not read biWidth in the info header.\n"); fclose(fp); return -1; } //读入 biHeight
if(fread(&bmih->biHeight,sizeof(LONG),1,fp)!=1) { printf("Can not read biHeight in the info header.\n"); fclose(fp); return -1; } //读入 biPlanes if(fread(&bmih->biPlanes,sizeof(WORD),1,fp)!=1) { printf("Can not read biPlanes in the info header.\n"); fclose(fp); return -1; } //读入 biBitCount if(fread(&bmih->biBitCount,sizeof(WORD),1,fp)!=1) { printf("Can not read biBitCount in the info header.\n"); fclose(fp); return -1; } //读入 biCompression if(fread(&bmih->biCompression,sizeof(DWORD),1,fp)!=1) { printf("Can not read biCompression in the info header.\n"); fclose(fp); return -1; } //读入 biSizeImage if(fread(&bmih->biSizeImage,sizeof(DWORD),1,fp)!=1) { printf("Can not read biSizeImage in the info header.\n"); fclose(fp); return -1; } //读入 biXPelsPerMeter if(fread(&bmih->biXPelsPerMeter,sizeof(LONG),1,fp)!=1) { printf("Can not read biXPelsPerMeter in the info header.\n");
fclose(fp); return -1; } //读入 biYPelsPerMeter if(fread(&bmih->biYPelsPerMeter,sizeof(LONG),1,fp)!=1) { printf("Can not read biYPelsPerMeter in the info header.\n"); fclose(fp); return -1; } //读入 biClrUsed if(fread(&bmih->biClrUsed,sizeof(DWORD),1,fp)!=1) { printf("Can not read biClrUsed in the info header.\n"); fclose(fp); return -1; } //读入 biClrImportant if(fread(&bmih->biClrImportant,sizeof(DWORD),1,fp)!=1) { printf("Can not read biClrImportant in the info header.\n"); fclose(fp); return -1; } //关闭文件 fclose(fp); return 0; } //读取像素数据 int ReadPixelData(char *filepath) { BITMAPINFOHEADER bmih; BITMAPFILEHEADER bmfh; BYTE *imgdata; FILE *fp; int n; int width;
int height; int bitCount; long biSizeImage; int i; int j; long a[256]={0}; int p; DWORD dwLineBytes; //读入文件头 n=ReadFileHeader(filepath,&bmfh); if(n==-1) { printf("Can not read the file header of BMP file.\n"); return -1; } //读入信息头 n=ReadInfoHeader(filepath,&bmih); if(n==-1) { printf("Can not read the info header of BMP file.\n"); return -1; } //获取信息头有用信息 width=bmih.biWidth; height=bmih.biHeight; bitCount=bmih.biBitCount; biSizeImage=bmih.biSizeImage; dwLineBytes=GetLineBytes(width,bitCount); //printf("%ld\n",dwLineBytes); printf("位图宽:%ld\n",width); printf("位图高:%ld\n",height); printf("位图位数:%d\n",bitCount); printf("位图所占字节数:%ld\n",biSizeImage); fp = fopen(filepath,"rb"); if(!fp) { printf("Can not open the file:%s\n",filepath); return -1;
分享到:
收藏