#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <string.h>
#include <windows.h>
#define WIDTHBYTES(bits) (((bits)+31)/32*4)
void main()
{
BITMAPFILEHEADER bitHead;
BITMAPINFOHEADER bitInfoHead;
FILE *pfile;
char strFile[50];
printf("请输入要打开的文件名:");
scanf("%s",strFile);
pfile = fopen(strFile,"rb");//打开文件
if(pfile==NULL)
{
printf("\n文件打开失败!\n");
return;
}
printf("\n文件打开成功!\n");
unsigned short fileType;//定义文件头
fread(&fileType,sizeof(unsigned short),1,pfile);//读文件类型
rewind(pfile); //将指针返回文件头
printf("%x",fileType);
printf("\n");
if(fileType != 0x4d42)
{
printf("\n该文件不是.bmp格式的文件.\n");
return;
}
/****************************************************************前面的不管*****************************/
/******************************************************读取文件头信息*********************************/
fread(&bitHead,sizeof(BITMAPFILEHEADER),1,pfile);
fread(&bitInfoHead,sizeof(BITMAPINFOHEADER),1,pfile);
RGBQUAD *pRgb ;
long nPlantNum;//定义使用颜色数的个数
switch (bitInfoHead.biBitCount)
{
case 1:nPlantNum=2;break;
case 2:nPlantNum=4;break;
case 4:nPlantNum=16;break;
case 8:nPlantNum=256;break;
case 16:nPlantNum=256*256;break;
case 24:nPlantNum=256;break;
}
pRgb=(RGBQUAD *)malloc(nPlantNum*sizeof(RGBQUAD));
memset(pRgb,0,nPlantNum*sizeof(RGBQUAD));
if(bitInfoHead.biBitCount < 24)
{
fread(pRgb,sizeof(RGBQUAD),nPlantNum,pfile);
/**********************************灰度处理******************************************/
int temp;
for (int i =0; i<nPlantNum;i++)
{
temp=int( (float)pRgb[i].rgbRed * 0.299+\
(float)pRgb[i].rgbGreen * 0.587+(float)pRgb[i].rgbBlue * 0.114);
pRgb[i].rgbRed = temp;
pRgb[i].rgbGreen = temp;
pRgb[i].rgbBlue = temp;
}
}
/**********************************灰度处理******************************************/
if(bitInfoHead.biBitCount == 24)//为24位的位图文件灰度处理创建调色板
{
for (int i =0; i<nPlantNum;i++)
{
pRgb[i].rgbRed = pRgb[i].rgbGreen = pRgb[i].rgbBlue = i;
}
}
int width = bitInfoHead.biWidth;
int height = bitInfoHead.biHeight;
int l_width = WIDTHBYTES(width* bitInfoHead.biBitCount);
long nData = height*l_width;
unsigned char *pColorData=(unsigned char *)malloc(nData);
memset(pColorData,0,height*l_width);
fread(pColorData,1,nData,pfile);
unsigned char *pColorData2=(unsigned char *)malloc(nData);
memset(pColorData2,0,nData);
if(bitInfoHead.biBitCount == 24) //位图为24位真彩色
{ int k;
int temp;
int index = 0;
for(int i=0;i<height;i++)
{
for(int j=0;j<width;j++)//把每一个的像素点的数值弄成一样
{
k = i*l_width + j*3;
temp=int( (float)pColorData[k] * 0.299+\
(float)pColorData[k+1]* 0.587+(float)pColorData[k+2] * 0.114);
index++;
for(int m=0;m<nPlantNum;m++)
{
if(pRgb[m].rgbRed==temp)
{
pColorData2[index]=m;
break;
}
}
}
}
}
/**************************文件处理后另存*******************************/
printf("\n请输入灰度处理后的另存文件名:");
scanf("%s",strFile);
pfile = fopen(strFile,"wb");//打开文件
if(pfile==NULL)
{
printf("\n文件另存失败!\n");
return;
}
if(bitInfoHead.biBitCount < 24)
{
fwrite(&bitHead,sizeof(BITMAPFILEHEADER),1,pfile);//写文件头
fwrite(&bitInfoHead,sizeof(BITMAPINFOHEADER),1,pfile);//写信息头
fwrite(pRgb,sizeof(RGBQUAD),nPlantNum,pfile); //写调色板
fwrite(pColorData,1,nData,pfile);//写位图数据
}
if(bitInfoHead.biBitCount == 24)
{
//修改部分文件头数据
//位图数据的偏移字节数做相应变化
bitHead.bfOffBits = sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+\
nPlantNum*sizeof(RGBQUAD);
//文件大小做相应变化
bitHead.bfSize = bitHead.bfOffBits + nData;
//修改部分信息头数据
//真彩位图灰度处理时必须为8
bitInfoHead.biBitCount = 8;
//实际位图数据占用的字节数做相应变化
bitInfoHead.biSizeImage = nData;//实际宽度乘以高度
//文件另存
fwrite(&bitHead,sizeof(BITMAPFILEHEADER),1,pfile);//写文件头
fwrite(&bitInfoHead,sizeof(BITMAPINFOHEADER),1,pfile);//写信息头
fwrite(pRgb,sizeof(tagRGBQUAD),nPlantNum,pfile);//写调色板
fwrite(pColorData2,1,nData,pfile);//写位图数据
free(pColorData2);//释放内存
}
/*******************************************************************************
printf("%s ",bitInfoHead.biCompression);
printf("\n");
**********************************************************************************/
fclose(pfile);
free(pRgb);
free(pColorData);
}