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 }