上一篇介绍过了位图的基本概念,相信大家对bmp格式的图片存储结构已经了解了,下面就以一个win32控制台程序来实现真彩图(也就是24位位图)转为为256级灰度图,这在图像处理上非常重要。
为什么用控制台程序而不是MFC等窗口程序呢,是因为这程序更能说明算法实现的过程,而不拘泥于MFC的框架下。
程序如下:(注释很好,不用过多解释)
#include <stdio.h> #include <windows.h> #define WIDTHBYTES(i) ( ( (i+31)/32 )*4) //使每一行的宽度是4个字节的倍数 #define IMAGETYPE 0x4d42 //表示字符BM int main(int argc,char* argv) { BITMAPFILEHEADER bmpfileheader; //文件头 BITMAPINFOHEADER bmpinfoheader; //信息头 unsigned char *matrix; //像素矩阵,用unsigned char是因为它的范围刚好为0—255 FILE *finput; //读取操作流 FILE *foutput; //出操作流 DWORD imageSize = 0; //图像像素数据部分大小 //打开文件 finput=fopen("picture.bmp","r+b"); if (finput == NULL) { printf("Open failed\n"); return EXIT_FAILURE; } else { printf("Open Successsfully\n"); } fread(&bmpfileheader,sizeof(BITMAPFILEHEADER),1,finput);//读取文件头 fread(&bmpinfoheader,sizeof(BITMAPINFOHEADER),1,finput);//读取信息头 //判断是否为24位真彩图 if ( bmpfileheader.bfType!=IMAGETYPE || bmpinfoheader.biBitCount != 24) { printf("The error picture!"); return EXIT_FAILURE; } //计算位图像素部分的大小,也可以是bmpinfoheader.biSizeImage 但它有时候是0,不可靠。 imageSize = WIDTHBYTES(bmpinfoheader.biWidth*bmpinfoheader.biBitCount) * bmpinfoheader.biHeight; matrix = new unsigned char[imageSize]; memset(matrix,0,imageSize); //读取象素矩阵 fread(matrix,1,imageSize,finput); fclose(finput); //每个像素点转化为灰度值,用的公式是:Gray = R*0.299 + G*0.587 + B*0.114 for(unsigned long k=0;k<imageSize;k=k+3) { *(matrix+k)=*(matrix+k+1)=*(matrix+k+2)=(*(matrix+k)*0.299+*(matrix+k+1)*0.587+*(matrix+k+2)*0.114); } //创建新的灰度图 foutput=fopen("test.bmp","w+b"); fwrite(&bmpfileheader,sizeof(BITMAPFILEHEADER),1,foutput); fwrite(&bmpinfoheader,sizeof(BITMAPINFOHEADER),1,foutput); fwrite(matrix,1,imageSize,foutput); fclose(foutput); delete []matrix; printf("转化成功\n"); return EXIT_SUCCESS; }
实现结果:把一张bmp格式的真彩图放在工程目录下,运行程序生成一个灰度图。