【转】真彩bmp图像转化为灰度图
感谢大神分享 原链接https://blog.****.net/u011450295/article/details/37316909
下面是用c语言实现的将真彩bmp图像转化为灰度图。
- #include "stdafx.h"
- #include<stdio.h>
- #include<windows.h>
- int _tmain(int argc, _TCHAR* argv[])
- {
- int bmpHeight;
- int bmpWidth;
- unsigned char *pBmpBuf;
- RGBQUAD *pColorTable;
- int biBitCount;
- //读取bmp文件
- FILE *fp=fopen("dog1.bmp","rb");
- if(fp==0)
- return 0;
- fseek(fp,sizeof(BITMAPFILEHEADER),0);
- BITMAPINFOHEADER head;
- fread(&head,40,1,fp);
- bmpHeight=head.biHeight;
- bmpWidth=head.biWidth;
- biBitCount=head.biBitCount;
- if(biBitCount==8)
- {
- pColorTable=new RGBQUAD[256];
- fread(pColorTable,sizeof(RGBQUAD),256,fp);
- }
- int LineByte=(bmpWidth*biBitCount/8+3)/4*4;//保证每一行字节数都为4的整数倍
- pBmpBuf=new unsigned char[LineByte*bmpHeight];
- fread(pBmpBuf,LineByte*bmpHeight,1,fp);
- fclose(fp);
- ////测试读取功能模块
- printf("bmpWidth:%d ,bmpHeight: %d,biBitCount:%d \n",bmpWidth,bmpHeight,biBitCount);
- //将24位真彩图灰度化并保存
- FILE *fp1=fopen("dog2.bmp","wb");
- if(fp1==0)
- return 0;
- int LineByte1=(bmpWidth*8/8+3)/4*4;
- //修改文件头,其中有两项需要修改,分别为bfSize和bfOffBits
- BITMAPFILEHEADER bfhead;
- bfhead.bfType=0x4D42;
- bfhead.bfSize=14+40+256*sizeof(RGBQUAD)+LineByte1*bmpHeight;//修改文件大小
- bfhead.bfReserved1=0;
- bfhead.bfReserved2=0;
- bfhead.bfOffBits=14+40+256*sizeof(RGBQUAD);//修改偏移字节数
- fwrite(&bfhead,14,1,fp1); //将修改后的文件头存入fp1;
- //修改信息头,其中有两项需要修改,1个位biBitCount:真彩图为24 ,应改成8;另一个是biSizeImage:由于每像素所占位数的变化,所以位图数据的大小发生变化
- BITMAPINFOHEADER head1;
- head1.biBitCount=8; //将每像素的位数改为8
- head1.biClrImportant=0;
- head1.biCompression=0;
- head1.biClrUsed=0;
- head1.biHeight=bmpHeight;
- head1.biWidth=bmpWidth;
- head1.biPlanes=1;
- head1.biSize=40;
- head1.biSizeImage=LineByte1*bmpHeight;//修改位图数据的大小
- head1.biXPelsPerMeter=0;
- head1.biYPelsPerMeter=0;
- fwrite(&head1,40,1,fp1); //将修改后的信息头存入fp1;
- if(biBitCount==24)//判断是否是真彩图,若是,由于真彩图没有颜色表,所以在变为灰度图后要加上颜色表
- {
- pColorTable=new RGBQUAD[256];
- for (int i = 0; i < 256; i++ )
- pColorTable[i].rgbRed = pColorTable[i].rgbGreen = pColorTable[i].rgbBlue = i; //是颜色表里的B、G、R分量都相等,且等于索引值
- }
- fwrite(pColorTable,sizeof(RGBQUAD),256,fp1); //将颜色表写入fp1;
- //写位图数据
- unsigned char *pBmpBuf1;
- pBmpBuf1= new unsigned char[LineByte1*bmpHeight];
- for(int i=0;i<bmpHeight;i++)
- for(int j=0;j<bmpWidth;j++)
- {
- unsigned char *pb1,*pb2;
- pb1=pBmpBuf+i*LineByte+j*3;
- int y=*(pb1)*0.299+*(pb1+1)*0.587+*(pb1+2)*0.114; //将每一个像素都按公式y=B*0.299+G*0.587+R*0.114进行转化
- pb2=pBmpBuf1+i*LineByte1+j;
- *pb2=y;
- }
- if(biBitCount==8)
- fwrite(pBmpBuf,LineByte*bmpHeight,1,fp1);
- else
- fwrite(pBmpBuf1,LineByte1*bmpHeight,1,fp1);
- fclose(fp1);
- system("pause");
- return 0;
- }