用c语言对bitmap文件进行读取(256灰度与24位色)

「用c语言对bitmap文件进行读取(256灰度与24位色)」の編集履歴(バックアップ)一覧はこちら

用c语言对bitmap文件进行读取(256灰度与24位色)」(2011/10/11 (火) 22:55:16) の最新版変更点

追加された行は緑色になります。

削除された行は赤色になります。

http://iiec.cqu.edu.cn/wiki/index.php?title=%E7%94%A8c%E8%AF%AD%E8%A8%80%E5%AF%B9bitmap%E6%96%87%E4%BB%B6%E8%BF%9B%E8%A1%8C%E8%AF%BB%E5%8F%96%28256%E7%81%B0%E5%BA%A6%E4%B8%8E24%E4%BD%8D%E8%89%B2%29&oldid=5050 用c语言对bitmap文件进行读取(256灰度与24位色) 在2008年7月17日 (四) 07:53由Zhouxl (对话 | 贡献)所做的修订版本 (差异) ←上一修订 | 当前修订 (差异) | 下一修订→ (差异) 1.关于BITMAP图像的结构: 24位色的BITMAP图像结构按顺序分为BITMAPFILEHEADER(文件头),BITMAPINFOHEADER(信息头),后面接着为象素信息; 非24位色在BITMAPINFOHEADER(信息头)之后还有一个RGBQUAD(调色板)结构信息,然后接着才是象素信息. 下面是三个结构体的信息: struct BITMAPFILEHEADER { unsigned int bftype;//文件类型是否为BMP文件 unsigned long bfsize;//文件大小,以字节为单位 unsigned int bfreserverd1;//文件保留字,必须为0 unsigned int bfreserverd2;//文件保留字,必须为0 unsigned long bfOffBits;//文件头的偏移量表示,以字节为单位 }; struct BITMAPINFOHEADER { int bisize;//本结构大小字节为单位 int width;//图形宽度以象素为单位 int height;//图形高度以象素为单位 int planes;//目标设备的级别,必须为1 int bitcount;//每个象素所需要的位数 int SizeImage; // 位图的大小,以字节为单位 int compression;//是否为压缩 int xpermeter;//位图水平分辨率,每米像素数 int ypermeter;// 位图垂直分辨率,每米像素数 int ClrUsed;// 位图实际使用的颜色表中的颜色数 int ClrImportant;// 位图显示过程中重要的颜色数 }; struct RGBQUAD { BYTE rgbBlue; // 蓝色的亮度(值范围为0-255) BYTE rgbGreen; // 绿色的亮度(值范围为0-255) BYTE rgbRed; // 红色的亮度(值范围为0-255) BYTE rgbReserved;// 保留,必须为0 }; 关于调色板的原理: 如果对每一个象素都用RGB 3个分量表示,一幅100*100象素的16色图,若按3字节来储存,将占用100*100*3 = 30 000byte的空间,而一般图片都远大于100*100,这将导致大量的空间被占用,于是为颜色设计一个表:表的每行记录记录一种颜色的RGB值,当需要表示一象素颜色的时候,只要指定该颜色位于表中的位置即可.对于16色图,表的每种颜色只需要4位就可以就可以表示出来,因此整个图像只需要100*100*0.5 = 5 000byte, 再加上颜色表所用的3*16=48字节,一共5 048byte就可以将一个30 000byte的图片表示出来,这样就节约了空间.这个颜色表就叫调色盘. 关于象素点阵: 在24位真彩色的象素点中,每个像素点用3个字节表示RGB三个值,而在256级灰度色中,由于采用了调色板的模式,因调色板中的颜色需要8位才能表示完整,所以每个象素点用1个字节(即8bits)来标识调色板中对应的颜色. 2.对BITMAP文件的读取 根据以上对BITMAP结构体的描述,下面我将采用代码的形式进行介绍 #include<stdio.h> #include<windows.h> void main() { BITMAPFILEHEADER bmpfileheader;//定义一个文件头的对象 BITMAPINFOHEADER bmpinfoheader;//定义一个信息头的对象 RGBQUAD bmpRGB[256];//定义的一个256级灰度的颜色表 FILE *stream;//BITMAP文件结构体读取操作流 FILE *store;//BITMAP文件象素读取操作流 FILE *clear;//为pic.txt文本文件清空内容 BYTE* pixelmatrix;//用以储存象素矩阵 int sum_pixel;//求出总共象素所占内存区域的大小 stream = fopen("test.bmp","r+b");//以可读写二进制形式打开test.bmp文件 if (stream == NULL) { cout<<"Open failed\n"; return; } else cout<<"Open Successsfully\n"; /** *取BMP文件头信息 */ fread(&bmpfileheader,sizeof(BITMAPFILEHEADER),1,stream);//从stream文件流读取BMP文件头信息 printf("type=%d\nsize=%d\nreserverd1=%d\nreserverd2=%d\nbfOffBits=%d\n", bmpfileheader.bfType,bmpfileheader.bfSize,bmpfileheader.bfReserved1, bmpfileheader.bfReserved2,bmpfileheader.bfOffBits); /** *取BMP信息头信息 */ fread(&bmpinfoheader,sizeof(BITMAPINFOHEADER),1,stream);//从stream文件流读取BMP文件头信息 printf("biSize=%d\nbiWidth=%d\nbiHeight=%d\nbiPlanes=%d\nbiBitCount=%d\nbiCompression=% d\nbiSizeImage=%d\nbiXPelsPerMeter=%d\nbiYPelsPerMeter=%d\nbiClrUsed=%d\nbiClrImportant=%d\n", bmpinfoheader.biSize,bmpinfoheader.biWidth,bmpinfoheader.biHeight, bmpinfoheader.biPlanes,bmpinfoheader.biBitCount,bmpinfoheader.biCompression, bmpinfoheader.biSizeImage,bmpinfoheader.biXPelsPerMeter,bmpinfoheader.biYPelsPerMeter, bmpinfoheader.biClrUsed,bmpinfoheader.biClrImportant); /** *取BMP调色盘信息 */ if (bmpinfoheader.biBitCount != 24)//当且仅当颜色位数不是24位色时才读取调色盘信息 { fread(&bmpRGB,sizeof(RGBQUAD),256,stream);//读取256个调色板的每个的颜色 for (int k = 0 ; k<256 ; k++) printf("rgbBlue=%d\nrgbGreen=%d\nrgbRed=%d\nrgbReserved=%d\n", bmpRGB[k].rgbBlue,bmpRGB[k].rgbGreen,bmpRGB[k].rgbRed,bmpRGB[k].rgbReserved); } /** *取象素信息 */ pixelmatrix = new BYTE[bmpinfoheader.biSizeImage];//按照图片的大小给BYTE数组分配内存空间 memset(pixelmatrix,0,bmpinfoheader.biSizeImage);//对数组的每个值都进行初始化 fread(pixelmatrix,1,bmpinfoheader.biSizeImage,stream);//读取象素信息 fclose(stream);//关闭文件操作流 /** *此处将象素信息写入txt文档 *1.首先清空TXT文档 *2.然后再写入 */ clear = fopen("pic.txt","w");//以写("w")形式打开将会清空所打开的文件,详细见MSDN->fopen fclose(clear);//关闭文件操作流 store = fopen("pic.txt","ab"); for (int j = 0;j<bmpinfoheader.biSizeImage;j++)//当前位置小于总的象素个数时继续循环 fprintf(store,"%d\n",pixelmatrix[j]); fclose(store);//关闭文件操作流 ///////////////////////////////////////////////////////////////////////// char reply;//保持当前画面 cin>>reply; } 3.注意事项 BITMAP的文件是按照固定的顺序组织起来的,所以不能随便更改结构体读取的顺序,不然将会导致信息错误 在向文本文件写入的时候,要使用fprintf进行格式化写入,不然将导致TXT乱码

表示オプション

横に並べて表示:
変化行の前後のみ表示: