#include <fstream>#include <iostream>#include "Windows.h" #include "stdio.h"#include "string.h"using namespace std;typedef unsigned char var8;typedef unsigned int uvar32;typedef unsigned short int uvar16;typedef struct { var8 Blue,Green,Red,Reserved;} Palette;
#define xResolution 1024#define yResolution 768
unsigned char *pBmpBuf;//读入图像数据的指针int bmpWidth;//图像的宽int bmpHeight;//图像的高RGBQUAD *pColorTable;//颜色表指针int biBitCount;//图像类型,每像素位数 /************************************************************************ 函数名称:* readBmp() **函数参数: * char *bmpName -文件名字及路径 **返回值: * 0为失败,1为成功* *说明:给定一个图像文件名及其路径,读图像的位图数据、宽、高、颜色表及每像素 * 位数等数据进内存,存放在相应的全局变量中***********************************************************************/bool readBmp(char *bmpName){//二进制读方式打开指定的图像文件 FILE *fp=fopen(bmpName,"rb"); if(fp==0) return 0;//跳过位图文件头结构BITMAPFILEHEADER fseek(fp, sizeof(BITMAPFILEHEADER),0); //定义位图信息头结构变量,读取位图信息头进内存,存放在变量head中
BITMAPINFOHEADER head; fread(&head, sizeof(BITMAPINFOHEADER), 1,fp); //获取图像宽、高、每像素所占位数等信息bmpWidth = head.biWidth;bmpHeight = head.biHeight;biBitCount = head.biBitCount; //定义变量,计算图像每行像素所占的字节数(必须是4的倍数)int lineByte=(bmpWidth * biBitCount/8+3)/4*4; //灰度图像有颜色表,且颜色表表项为256if(biBitCount==8){//申请颜色表所需要的空间,读颜色表进内存pColorTable=new RGBQUAD[256];fread(pColorTable,sizeof(RGBQUAD),256,fp);} //申请位图数据所需要的空间,读位图数据进内存pBmpBuf=new unsigned char[lineByte * bmpHeight];fread(pBmpBuf,1,lineByte * bmpHeight,fp); //关闭文件fclose(fp); return 1;} /****************************************** 函数名称:* saveBmp() ** 函数参数:* char *bmpName-文件名字及路径* unsigned char *imgBuf-待存盘的位图数据* int width-以像素为单位待存盘位图的宽* int height-以像素为单位待存盘位图高* int biBitCount-每像素所占位数* RGBQUAD *pColorTable-颜色表指针*返回值: 0为失败,1为成功**说明:给定一个图像位图数据、宽、高、颜色表指针及每像素所占的位数等信息,* 将其写到指定文件中***********************************************************************/bool saveBmp(char *bmpName, unsigned char *imgBuf, int width, int height, int biBitCount,RGBQUAD *pColorTable){//如果位图数据指针为0,则没有数据传入,函数返回 if(!imgBuf)return 0; //颜色表大小,以字节为单位,灰度图像颜色表为1024字节,彩色图像颜色表大小为0 int colorTablesize=0; if(biBitCount==8)colorTablesize=1024; //待存储图像数据每行字节数为4的倍数 int lineByte=(width * biBitCount/8+3)/4*4; //以二进制写的方式打开文件 // char *wenjian; FILE *fp=fopen(bmpName,"wb"); //FILE *fp1=fopen("wenjian.txt","wb"); if(fp==0) return 0; //申请位图文件头结构变量,填写文件头信息 BITMAPFILEHEADER fileHead; fileHead.bfType = 0x4D42; //bmp类型 //bfSize是图像文件4个组成部分之和 fileHead.bfSize= sizeof(BITMAPFILEHEADER)+ sizeof(BITMAPINFOHEADER)+ colorTablesize + lineByte*height; fileHead.bfReserved1 = 0; fileHead.bfReserved2 =0; //bfOffBits是图像文件前3个部分所需空间之和 fileHead.bfOffBits=54+colorTablesize; //写文件头进文件 fwrite(&fileHead, sizeof(BITMAPFILEHEADER),1, fp); // fwrite(&fileHead, sizeof(BITMAPFILEHEADER),1, fp1); //申请位图信息头 结构变量,填写信息头信息 BITMAPINFOHEADER head; head.biBitCount=biBitCount; head.biClrImportant=0; head.biClrUsed=0; head.biCompression=0; head.biHeight=height; head.biPlanes=1; head.biSize=40; head.biSizeImage=lineByte*height; head.biWidth=width; head.biXPelsPerMeter=0; head.biYPelsPerMeter=0; //写位图信息头进内存 fwrite(&head, sizeof(BITMAPINFOHEADER),1, fp); //fwrite(&head, sizeof(BITMAPINFOHEADER),1, fp1); //如果灰度图像,有颜色表,写入文件 if(biBitCount==8) { fwrite(pColorTable, sizeof(RGBQUAD),256, fp); //fwrite(pColorTable, sizeof(RGBQUAD),256, fp1); } //写位图数据进文件 fwrite(imgBuf, height*lineByte, 1, fp); // fwrite(imgBuf, height*lineByte, 1, fp1); //关闭文件 fclose(fp); //fclose(fp1); return 1;} int main(){ //读入指定BMP文件进内存 char readPath[]="dog.BMP"; readBmp(readPath); //输出图像的信息 printf("width=%d,height=%d, biBitCount=%d/n",bmpWidth,bmpHeight, biBitCount); //将图像数据存盘 char writePath[]="dogcpy.BMP"; saveBmp(writePath, pBmpBuf, bmpWidth, bmpHeight, biBitCount, pColorTable); //清除缓冲区,pBmpBuf和pColorTable是全局变量,在文件读入时申请的空间 delete []pBmpBuf; if(biBitCount==8)delete []pColorTable;
uvar32 Size,Offset,Height,Width,Compress,Reserved, InfoHeaderSize,Colors,ImportantColors,DataSize,HResolution,VResolution; uvar16 Planes,Bit; int i,j; var8 type[2],imdata[yResolution][xResolution];// memset(imdata,0,2000*2000); Palette Rgbquad; ifstream fin; fin.open("dog.bmp",ios::binary); /*以二进制读方式打开该文件,一定要二进制的!*/ if(!fin) { cout<<"No this file!/n"; return 1; } fin.read((char*)&type ,2); cout<<"file type: "<<type[0]<<type[1]<<endl; /* 两字节的内容用来识别位图的类型,偏移量0,结果file type: BM*/ fin.read((char*)&Size ,sizeof(uvar32)); cout<<"file size: "<<Size<<endl; /*整个文件的大小,偏移量2,结果file size: 66614*/ fin.read((char*)&Reserved,sizeof(uvar32)); cout<<"Reserved dword: "<<Reserved<<endl; /*保留,必须设置为0, 偏移量6,结果Reserved dword: 0*/ fin.read((char*)&Offset ,sizeof(uvar32)); cout<<"Offset: "<<Offset<<endl; /*从文件开始到位图数据开始之间的数据(bitmap data)之间的偏移量 ,偏移量10,结果Offset: 1078。位图数据为256*256, 65536(位图数据)+1078(偏移量)=66614(文件大小)*/ fin.read((char*)&InfoHeaderSize,sizeof(uvar32)); cout<<"Bitmap Info Header Size: "<<InfoHeaderSize<<endl; /*位图信息头(Bitmap Info Header)的长度,偏移量14, 结果 Bitmap Info Header Size: 40*/ fin.read((char*)&Width,sizeof(uvar32)); cout<<"Bitmap Width: "<<Width<<endl; /*位图的宽度,以象素为单位,偏移量18,Bitmap Width: 256*/ fin.read((char*)&Height,sizeof(uvar32)); cout<<"Bitmap Height: "<<Height<<endl; /*位图的高度,以象素为单位,如果该值是一个正数,说明图像是倒向的, 如果该值是一个负数,则说明图像是正向的。偏移量22,Bitmap Height: 256*/ fin.read((char*)&Planes,sizeof(uvar16)); cout<<"Bitmap Planes: "<<Planes<<endl; /*位图的位面数(注:该值将总是1),偏移量26,Bitmap Planes: 1*/ fin.read((char*)&Bit,sizeof(uvar16)); cout<<"Bits per Pixel: "<<Bit<<endl; /*每个象素的位数,偏移量28,256色应该8bit,Bits per Pixel: 8*/ fin.read((char*)&Compress,sizeof(uvar32)); cout<<"Compresssion Y or N: "<<Compress<<endl; /*压缩说明0为不压缩,偏移量30,Compresssion Y or N: 0*/ if(Compress) { fin.close();return 2;} fin.read((char*)&DataSize,sizeof(uvar32)); cout<<"Data Size: "<<DataSize<<endl; /*用字节数表示的位图数据的大小,偏移量34,256*256=65536, Data Size: 65536*/ fin.read((char*)&HResolution,sizeof(uvar32)); cout<<"HResolution: "<<HResolution<<endl; /*用象素/米表示的水平分辨率,偏移量38,HResolution: 0*/ fin.read((char*)&VResolution,sizeof(uvar32)); cout<<"VResolution: "<<VResolution<<endl; /*用象素/米表示的垂直分辨率,偏移量42,VResolution: 0*/ fin.read((char*)&Colors,sizeof(uvar32)); cout<<"Colors: "<<Colors<<endl; /*位图使用的颜色数,256色,偏移量46,Colors: 256*/ fin.read((char*)&ImportantColors,sizeof(uvar32)); cout<<"ImportantColors: "<<ImportantColors<<endl; /*指定重要的颜色数。当该域的值等于颜色数时(或者等于0时), 表示所有颜色都一样重要。偏移量50,ImportantColors: 0*/
int platte[256][4];
for(i=0;i<256/*+1000*/;i++) { fin.read((char*)&Rgbquad,sizeof(Palette)); platte[i][0] = int(Rgbquad.Blue); platte[i][1] = int(Rgbquad.Green); platte[i][2] = int(Rgbquad.Red); platte[i][3] = (platte[i][0] + platte[i][1] + platte[i][2])/3; cout<<int(Rgbquad.Blue)<<" "<<int(Rgbquad.Green)<<" "<<int(Rgbquad.Red) <<" "<<int(Rgbquad.Reserved)<<endl; } /*调色板规范。对于调色板中的每个表项,这4个字节用下述方法来 描述RGB的值:1字节用于蓝色分量 ,1字节用于绿色分量 ,1字节用于红色分量 1字节用于填充符(设置为0),偏移量由54到54+255*4=1074,对于彩色图像R,G,B 有各自的分量,对与黑白图像,R=G=B=灰度级。输出结果有 0 0 0 0,1 1 1 0… 255 255 255 0*/ fstream outfile; outfile.open("bitmap.txt",ios::out);
fin.seekg(Offset,ios::beg);
int maxValue = yResolution*xResolution; unsigned char tmpChar;// for (i=0; i<maxValue; i++)// {// fin.read((char*)&tmpChar, sizeof(unsigned char));// outfile<<platte[(int)tmpChar][3];// if (i!=maxValue-1)// {// outfile<<",";// }// outfile.write((char*)&tmpChar, sizeof(unsigned char));// }
var8 readChar; for( i=yResolution-1;i>=0;i--) { for(j=0;j<xResolution;j++) { fin.read((char*)&imdata[i][j],sizeof(var8)); // } } for (i=0; i<yResolution; i++) { for (j=0; j<xResolution; j++) { outfile<<platte[(int)imdata[i][j]][3]<<" "; // outfile.write((char*)&imdata[i][j], sizeof(var8)); } outfile<<"/n"; } /*直接把65536个像素的灰度读入数组imdata中,由于前面调色板的格式,读出的数据无 需 索引调色板。由于Height值大于零,图像倒置的,开始读入的数据是图像最后一行的灰 度值。*/// for(i=0; i<100; i++)// cout<<(int)imdata[yResolution-1][i]<<" ";
outfile.flush(); outfile.close(); return 0; /*以上数据结果与Matlab的imfinfo()和imread()的结果相吻合。 读出数据后,就可以进行直方图统计,fft2运算了。*/}