图像输出矩阵及还原成图像


#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;
//灰度图像有颜色表,且颜色表表项为256
if(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运算了。*/
}

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值