彩色bmp图片转灰度

下面这个程序可以将一个彩色的bmp格式图片转换灰度图片:
  1. #include <iostream.h>  
  2. #include <windows.h>  
  3. #include <stdio.h>  
  4.   
  5. /*BMP文件格式如下: 
  6. ㈠BITMAPFILEHEADER:位图文件头(只用于BMP文件) 
  7.                   bfType="BM" 
  8.                   bfSize 
  9.                   bfReserved1 
  10.                   bfReserved2 
  11.                   bfOffBits  从文件头到实际的位图数据的偏移字节数,即前三个部分长度之和 
  12. ㈡BITMAPINFOHEADER:位图信息头 
  13.                   biSize     这个结构的长度,为40个字节 
  14.                   biWidth    图象的宽度,单位是像素 
  15.                   biHeight   图象的高度,单位是像素 
  16.                   biPlanes 
  17.                   biBitCount 
  18.                   biCompression 
  19.                   biSizeImage 实际的位图字节数据占用的字节数 biSizeImage=biWidth_*biHeight,其中biWidth必须是4的整数倍 
  20.                               如果biCompression为BI_RGB,则该项可能为0 
  21.                   biXPelsPerMeter 
  22.                   biYPelsPerMeter 
  23.                   biClrUsed 
  24.                   biClrImportant 
  25. ㈢Palette         :调色板 
  26.                   灰度图象一般不需要考虑调色板,一般灰度图没有调色板 
  27. ㈣DIB Pixels      :图象数据 
  28. */  
  29.   
  30. BITMAPFILEHEADER bf;  //文件头  
  31. BITMAPINFOHEADER bi;  //信息头  
  32. RGBQUAD  *palette=NULL;     //调色板  
  33.   
  34. BYTE   *m_imagedata=NULL;   //图象数据指针  
  35. BYTE   *m_outputdata=NULL;  //输出数据指针  
  36. int     m_ImageWidth;   //图象宽度  
  37. int     m_ImageHeight;  //图象高度  
  38.   
  39. void main()  
  40. {  
  41.     FILE  *fp1,*fp2;  //文件指针,fp1为源文件,fp2为处理以后的文件  
  42.   
  43.     //打开文件,到文件指针  
  44.     if((fp1=fopen("test.bmp","rb"))==NULL)  
  45.     {  
  46.         MessageBox(NULL,"文件打开错误","warning",MB_OK);  
  47.     }  
  48.   
  49.     fread((LPSTR)&bf,sizeof(BITMAPFILEHEADER),1,fp1);  //读取文件头,读取以后文件指针在文件头末尾(即信息头)  
  50.   
  51.     //以下输出文件头的一些有用的数据  
  52.     int temp=bf.bfType;          //便于将开头两个字节转化为字符显示  
  53.     cout<<"BM标志:"<<(char *)(&temp)<<'\n';  
  54.     cout<<"偏移字节数:"<<bf.bfOffBits<<'\n';  
  55.   
  56.     fread((LPSTR)&bi,sizeof(BITMAPINFOHEADER),1,fp1);  //读取信息头  
  57.   
  58.     //以下输出信息头的一些有用的数据  
  59.     cout<<"图象宽度:"<<bi.biWidth<<'\n';  
  60.     cout<<"图象高度:"<<bi.biHeight<<'\n';  
  61.   
  62.     m_ImageWidth=bi.biWidth;             //给图象宽度赋值  
  63.     m_ImageHeight=bi.biHeight;           //给图象高度赋值  
  64.   
  65.     //每一行的数据必须是4的整数倍,如果不是,需要补齐  
  66.     while(m_ImageWidth%4!=0) //让宽度为4的整数倍  
  67.         m_ImageWidth++;  
  68.   
  69.     //读取调色板  
  70.     palette=(RGBQUAD *)new BYTE[bf.bfOffBits-sizeof(BITMAPFILEHEADER)-sizeof(BITMAPINFOHEADER)];  
  71.     fread(palette,bf.bfOffBits-sizeof(BITMAPFILEHEADER)-sizeof(BITMAPINFOHEADER),1,fp1);  
  72.   
  73.     m_imagedata= new BYTE[m_ImageHeight*m_ImageWidth*3];   //给图象数据指针分配空间  
  74.     fread(m_imagedata,m_ImageHeight*m_ImageWidth*3,1,fp1);  //读取图象数据  
  75.    
  76.     //图象数据是从第0行开始存储的,然后依次是第一行,第二行.......  
  77.     //图象数据读取以后就可以对其进行处理  
  78.     m_outputdata= new BYTE[m_ImageHeight*m_ImageWidth*3];   //给图象数据指针分配空间  
  79.     //这一部分添加对图象数据即m_imagedata处理的过程,处理结果放在m_outputdata中  
  80.     //如果想观察处理结果,可以把它们另存为一个文件,该文件使用原来文件的文件头,而图象数据为处理过的数据  
  81.     //这儿我仅把图象数据不作处理copy到输出图象中,得到的图象和原来一样  
  82.     for(int i=0;i<m_ImageHeight;i++)  
  83.     {  
  84.         for(int j=0;j<m_ImageWidth*3;j=j+3)  
  85.         {  
  86.             int k=m_ImageWidth*i*3+j;  
  87.             int gray=(int)(0.3*m_imagedata[k]+0.59*m_imagedata[k+1]+0.11*m_imagedata[k+2]);  
  88.             m_outputdata[k]=m_outputdata[k+1]=m_outputdata[k+2]=gray;  
  89.         }  
  90.     }  
  91.     //创建新文件  
  92.     if((fp2=fopen("result.bmp","wb"))==NULL)  
  93.     {  
  94.         MessageBox(NULL,"文件创建失败","warning",MB_OK);  
  95.     }  
  96.   
  97.     //写结果文件,文件信息部分用test文件的文件信息部分  
  98.     fwrite((LPSTR)&bf,sizeof(BITMAPFILEHEADER),1,fp2);  
  99.     fwrite((LPSTR)&bi,sizeof(BITMAPINFOHEADER),1,fp2);  
  100.     fwrite(palette,bf.bfOffBits-sizeof(BITMAPFILEHEADER)-sizeof(BITMAPINFOHEADER),1,fp2);  
  101.     fwrite(m_outputdata,m_ImageHeight*m_ImageWidth*3,1,fp2); //写像素数据  
  102.   
  103.     fclose(fp1);  //关闭文件  
  104.     fclose(fp2);  


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值