19,468
社区成员
发帖
与我相关
我的任务
分享
/********************************************************************
//函数名称:void COpenBmpView::OnBitmapGray()
//功能: 24位真彩色位图灰度化处理
*********************************************************************/
void COpenBmpView::OnBitmapGray()
{
// TODO: Add your command handler code here
UpdateData();
if(m_sourcefile==""||m_target_Grayfile=="")
return;
FILE *sourcefile,*targetfile;
//位图文件头和信息头
BITMAPFILEHEADER sourcefileheader,targetfileheader;
BITMAPINFOHEADER sourceinfoheader,targetinfoheader;
memset(&targetfileheader,0,sizeof(BITMAPFILEHEADER));
memset(&targetinfoheader,0,sizeof(BITMAPINFOHEADER));
sourcefile=fopen(m_sourcefile,"rb"); //以二进制形式读文件
fread((void*)&sourcefileheader,1,sizeof(BITMAPFILEHEADER),sourcefile);//提取原图文件头
if(sourcefileheader.bfType!=0x4d42)
{
fclose(sourcefile);
MessageBox("原图象不为BMP图象!");
return;
}
fread((void*)&sourceinfoheader,1,sizeof(BITMAPINFOHEADER),sourcefile);//提取文件信息头
if(sourceinfoheader.biBitCount!=24)
{
fclose(sourcefile);
MessageBox("原图象不为24位真彩色!");
return;
}
if(sourceinfoheader.biCompression!=BI_RGB)
{
fclose(sourcefile);
MessageBox("原图象为压缩后的图象,本程序不处理压缩过的图象!");
return;
}
//构造灰度图的文件头
targetfileheader.bfOffBits=54+sizeof(RGBQUAD)*256;
targetfileheader.bfSize=targetfileheader.bfOffBits+sourceinfoheader.biSizeImage/3;
targetfileheader.bfReserved1=0;
targetfileheader.bfReserved2=0;
targetfileheader.bfType=0x4d42;
//构造灰度图的信息头
targetinfoheader.biBitCount=8;
targetinfoheader.biSize=40;
targetinfoheader.biHeight=sourceinfoheader.biHeight;
targetinfoheader.biWidth=sourceinfoheader.biWidth;
targetinfoheader.biPlanes=1;
targetinfoheader.biCompression=BI_RGB;
targetinfoheader.biSizeImage=sourceinfoheader.biSizeImage/3;
targetinfoheader.biXPelsPerMeter=sourceinfoheader.biXPelsPerMeter;
targetinfoheader.biYPelsPerMeter=sourceinfoheader.biYPelsPerMeter;
targetinfoheader.biClrImportant=0;
targetinfoheader.biClrUsed=256;
//构造灰度图的调色板
RGBQUAD rgbquad[256];
int i,j,m,n,k;
for(i=0;i<256;i++)
{
rgbquad[i].rgbBlue=i;
rgbquad[i].rgbGreen=i;
rgbquad[i].rgbRed=i;
rgbquad[i].rgbReserved=0;
}
targetfile=fopen(m_target_Grayfile,"wb");
//写入灰度图的文件头,信息头和调色板信息
fwrite((void*)&targetfileheader,1,sizeof(BITMAPFILEHEADER),targetfile);
fwrite((void*)&targetinfoheader,1,sizeof(BITMAPINFOHEADER),targetfile);
fwrite((void*)&rgbquad,1,sizeof(RGBQUAD)*256,targetfile);
BYTE* sourcebuf;
BYTE* targetbuf;
//这里是因为BMP规定保存时长度和宽度必须是4的整数倍,如果不是则要补足
m=(targetinfoheader.biWidth/4)*4;
if(m<targetinfoheader.biWidth)
m=m+4;
n=(targetinfoheader.biHeight/4)*4;
if(n<targetinfoheader.biHeight)
n=n+4;
sourcebuf=(BYTE*)malloc(m*n*3);
//读取原图的颜色矩阵信息
fread(sourcebuf,1,m*n*3,sourcefile);
fclose(sourcefile);
targetbuf=(BYTE*)malloc(m*n);
BYTE color[3];
//通过原图颜色矩阵信息得到灰度图的矩阵信息
for(i=0;i<n;i++)
{
for(j=0;j<m;j++)
{
for(k=0; k<3; k++)
color[k]=sourcebuf[(i*m+j)*3+k];
targetbuf[(i*m)+j]=color[0]*0.114+color[1]*0.587+color[2]*0.299;
if(targetbuf[(i*m)+j]>255)
targetbuf[(i*m)+j]=255;
}
}
fwrite((void*)targetbuf,1,m*n+1,targetfile);
fclose(targetfile);
MessageBox("位图文件转换成功!");
Invalidate(TRUE); //重绘
}