1 /*************************************************
  2 Author:
  3 Date:2013-01-23
  4 **************************************************/
  5 #include "stdafx.h"
  6 //Visual studio 2010版中应该放到stdafx.h文件中的头文件们
  7 #include<math.h>
  8 #include <iomanip> 
  9 #include <stdlib.h>
 10 #include <windows.h>
 11 #include <stdio.h>
 12 #include <stdlib.h>
 13 #include <iostream>
 14 #include <fstream>
 15 //
 16 using namespace System;
 17 using namespace std;
 18 /*************************************************
 19 
 20 Function:       bitmapToGray
 21 
 22 Description:    将BMP格式的灰度图像或24位真彩图像二值化,并生成新图像
 23 
 24 Input:          srcBMP - 待处理的图像路径
 25 
 26 Output:         grayBMP - 处理后生成的新图像
 27 
 28 Return:         0 - 处理失败
 29                 1 - 处理成功
 30 
 31 *************************************************/
 32 
 33 int bitmapToGray(char *srcBMP,char *grayBMP)
 34 {
 35     unsigned char *Bmp24Buf,*Bmp8Buf;    
 36     int height,width,bitCount;
 37     BITMAPFILEHEADER bmpFileHeader;
 38     BITMAPINFOHEADER bmpInfoHeader;
 39     FILE *rfp,*wfp;
 40     RGBQUAD *pColorTable;
 41     //读取原文件
 42     rfp=fopen(srcBMP,"rb");
 43     if(rfp==NULL)
 44     {
 45         printf("文件不存在!\n");
 46         return 0;
 47     }
 48     //读取文件头
 49     fread(&bmpFileHeader,sizeof(BITMAPFILEHEADER),1,rfp);
 50     //读取文件信息
 51     fread(&bmpInfoHeader,sizeof(BITMAPINFOHEADER),1,rfp);
 52     width = bmpInfoHeader.biWidth;
 53     height = bmpInfoHeader.biHeight;
 54     bitCount = bmpInfoHeader.biBitCount;
 55 
 56     //定义变量,计算图像每行像素所占的字节数(必须是4的倍数)
 57     int lineByte=(width * bitCount/8+3)/4*4;
 58     //灰度图像有颜色表,且颜色表表项为256
 59     pColorTable=new RGBQUAD[256];
 60     if(bitCount==8)
 61     {
 62         //申请颜色表所需要的空间,读颜色表进内存        
 63         fread(pColorTable,sizeof(RGBQUAD),256,rfp);
 64         Bmp8Buf=new unsigned char[lineByte * height];
 65         fread(Bmp8Buf,1,lineByte * height,rfp);
 66         //二值化
 67         for(int i=0;i<height;i++)
 68          {
 69              for(int j=0;j<lineByte;j++)
 70              {
 71                  if(Bmp8Buf[i*lineByte+j]>128)
 72                      Bmp8Buf[i*lineByte+j]=255;
 73                  else  Bmp8Buf[i*lineByte+j]=0;
 74              }
 75          }
 76         //关闭文件
 77         fclose(rfp);
 78         //写文件
 79         wfp=fopen(grayBMP,"wb");
 80         if(wfp==NULL)
 81         {
 82             printf("open savefile error\n");
 83             return 0;
 84         }
 85         fwrite(&bmpFileHeader,sizeof(BITMAPFILEHEADER),1,wfp);
 86         fwrite(&bmpInfoHeader,sizeof(BITMAPINFOHEADER),1,wfp);
 87         fwrite(pColorTable,sizeof(RGBQUAD),256,wfp);
 88         fwrite(Bmp8Buf,sizeof(unsigned char),lineByte * height,wfp);
 89         fclose(wfp);
 90     }
 91     else if(bitCount==24)
 92     {
 93         int lineByte24to8=(width+3)/4*4; //灰度图实际每行像素数        
 94         //文件信息头
 95         bmpInfoHeader.biBitCount = 8;
 96         bmpInfoHeader.biSizeImage = lineByte24to8 * height;
 97         //文件头
 98         bmpFileHeader.bfOffBits = sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+256*sizeof(RGBQUAD);
 99         bmpFileHeader.bfSize = bmpFileHeader.bfOffBits + bmpInfoHeader.biSizeImage;
100         //颜色表
101         for(int i=0;i<256;i++)
102         {
103             pColorTable[i].rgbBlue=i;
104             pColorTable[i].rgbGreen=i;
105             pColorTable[i].rgbRed=i;
106             pColorTable[i].rgbReserved=0;
107         }
108         //二值化
109         Bmp24Buf=new unsigned char[lineByte * height];
110         Bmp8Buf=new unsigned char[lineByte24to8 * height];
111         fread(Bmp24Buf,1,lineByte * height,rfp);
112         for(int i=0;i<height;i++)
113          {
114              for(int j=0;j<lineByte24to8;j++)
115              {
116                  Bmp8Buf[i*lineByte24to8+j]=Bmp24Buf[i*lineByte+j*3]*0.299+Bmp24Buf[i*lineByte+j*3+1]*0.587+Bmp24Buf[i*lineByte+j*3+2]*0.114;
117                  if(Bmp8Buf[i*lineByte24to8+j]>128)
118                      Bmp8Buf[i*lineByte24to8+j]=255;
119                  else  Bmp8Buf[i*lineByte24to8+j]=0;
120              }
121          }
122 
123         //关闭文件
124         fclose(rfp);
125         //写文件
126         wfp=fopen(grayBMP,"wb");
127         if(wfp==NULL)
128         {
129             printf("open savefile error\n");
130             return 0;
131         }
132         fwrite(&bmpFileHeader,sizeof(BITMAPFILEHEADER),1,wfp);
133         fwrite(&bmpInfoHeader,sizeof(BITMAPINFOHEADER),1,wfp);
134         fwrite(pColorTable,sizeof(RGBQUAD),256,wfp);
135         fwrite(Bmp8Buf,1,lineByte24to8 * height,wfp);
136         fclose(wfp);
137     }    
138     if(Bmp8Buf!=NULL)
139     {
140         delete Bmp8Buf;
141     }
142     if(Bmp24Buf!=NULL)
143     {
144         delete Bmp24Buf;
145     }
146     return 1;
147 }
148 
149 void main( )
150 {
151     bitmapToGray("songbie.bmp","gg.bmp");
152 }