上一篇介紹過了位元影像的基本概念,相信大家對bmp格式的圖片儲存結構已經瞭解了,下面就以一個win32控制台程式來實現真彩圖(也就是24位位元影像)轉為為256級灰階圖,這在影像處理上非常重要。
為什麼用控制台程式而不是MFC等視窗程序呢,是因為這程式更能說明演算法實現的過程,而不拘泥於MFC的架構下。
程式如下:(注釋很好,不用過多解釋)
#include <stdio.h> #include <windows.h>#define WIDTHBYTES(i) ( ( (i+31)/32 )*4) //使每一行的寬度是4個位元組的倍數#define IMAGETYPE 0x4d42 //表示字元BMint main(int argc,char* argv){BITMAPFILEHEADER bmpfileheader; //檔案頭BITMAPINFOHEADER bmpinfoheader; //資訊頭 unsigned char *matrix; //像素矩陣,用unsigned char是因為它的範圍剛好為0—255FILE *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.114for(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格式的真彩圖放在工程目錄下,運行程式產生一個灰階圖。