彩色bmp圖片轉灰度

下面這個程序可以將一個彩色的bmp格式圖片轉換灰度圖片:
  1. #include <iostream.h>  
  2. #include <windows.h>  
  3. #include <stdio.h>  
  4.   
  5. /*BMP文件格式如下: 
  6. ㈠BITMAPFILEHEADER:位圖文件頭(只用於BMP文件) 
  7.                   bfType="BM" 
  8.                   bfSize 
  9.                   bfReserved1 
  10.                   bfReserved2 
  11.                   bfOffBits  從文件頭到實際的位圖數據的偏移字節數,即前三個部分長度之和 
  12. ㈡BITMAPINFOHEADER:位圖信息頭 
  13.                   biSize     這個結構的長度,爲40個字節 
  14.                   biWidth    圖象的寬度,單位是像素 
  15.                   biHeight   圖象的高度,單位是像素 
  16.                   biPlanes 
  17.                   biBitCount 
  18.                   biCompression 
  19.                   biSizeImage 實際的位圖字節數據佔用的字節數 biSizeImage=biWidth_*biHeight,其中biWidth必須是4的整數倍 
  20.                               如果biCompression爲BI_RGB,則該項可能爲0 
  21.                   biXPelsPerMeter 
  22.                   biYPelsPerMeter 
  23.                   biClrUsed 
  24.                   biClrImportant 
  25. ㈢Palette         :調色板 
  26.                   灰度圖象一般不需要考慮調色板,一般灰度圖沒有調色板 
  27. ㈣DIB Pixels      :圖象數據 
  28. */  
  29.   
  30. BITMAPFILEHEADER bf;  //文件頭  
  31. BITMAPINFOHEADER bi;  //信息頭  
  32. RGBQUAD  *palette=NULL;     //調色板  
  33.   
  34. BYTE   *m_imagedata=NULL;   //圖象數據指針  
  35. BYTE   *m_outputdata=NULL;  //輸出數據指針  
  36. int     m_ImageWidth;   //圖象寬度  
  37. int     m_ImageHeight;  //圖象高度  
  38.   
  39. void main()  
  40. {  
  41.     FILE  *fp1,*fp2;  //文件指針,fp1爲源文件,fp2爲處理以後的文件  
  42.   
  43.     //打開文件,到文件指針  
  44.     if((fp1=fopen("test.bmp","rb"))==NULL)  
  45.     {  
  46.         MessageBox(NULL,"文件打開錯誤","warning",MB_OK);  
  47.     }  
  48.   
  49.     fread((LPSTR)&bf,sizeof(BITMAPFILEHEADER),1,fp1);  //讀取文件頭,讀取以後文件指針在文件頭末尾(即信息頭)  
  50.   
  51.     //以下輸出文件頭的一些有用的數據  
  52.     int temp=bf.bfType;          //便於將開頭兩個字節轉化爲字符顯示  
  53.     cout<<"BM標誌:"<<(char *)(&temp)<<'\n';  
  54.     cout<<"偏移字節數:"<<bf.bfOffBits<<'\n';  
  55.   
  56.     fread((LPSTR)&bi,sizeof(BITMAPINFOHEADER),1,fp1);  //讀取信息頭  
  57.   
  58.     //以下輸出信息頭的一些有用的數據  
  59.     cout<<"圖象寬度:"<<bi.biWidth<<'\n';  
  60.     cout<<"圖象高度:"<<bi.biHeight<<'\n';  
  61.   
  62.     m_ImageWidth=bi.biWidth;             //給圖象寬度賦值  
  63.     m_ImageHeight=bi.biHeight;           //給圖象高度賦值  
  64.   
  65.     //每一行的數據必須是4的整數倍,如果不是,需要補齊  
  66.     while(m_ImageWidth%4!=0) //讓寬度爲4的整數倍  
  67.         m_ImageWidth++;  
  68.   
  69.     //讀取調色板  
  70.     palette=(RGBQUAD *)new BYTE[bf.bfOffBits-sizeof(BITMAPFILEHEADER)-sizeof(BITMAPINFOHEADER)];  
  71.     fread(palette,bf.bfOffBits-sizeof(BITMAPFILEHEADER)-sizeof(BITMAPINFOHEADER),1,fp1);  
  72.   
  73.     m_imagedata= new BYTE[m_ImageHeight*m_ImageWidth*3];   //給圖象數據指針分配空間  
  74.     fread(m_imagedata,m_ImageHeight*m_ImageWidth*3,1,fp1);  //讀取圖象數據  
  75.    
  76.     //圖象數據是從第0行開始存儲的,然後依次是第一行,第二行.......  
  77.     //圖象數據讀取以後就可以對其進行處理  
  78.     m_outputdata= new BYTE[m_ImageHeight*m_ImageWidth*3];   //給圖象數據指針分配空間  
  79.     //這一部分添加對圖象數據即m_imagedata處理的過程,處理結果放在m_outputdata中  
  80.     //如果想觀察處理結果,可以把它們另存爲一個文件,該文件使用原來文件的文件頭,而圖象數據爲處理過的數據  
  81.     //這兒我僅把圖象數據不作處理copy到輸出圖象中,得到的圖象和原來一樣  
  82.     for(int i=0;i<m_ImageHeight;i++)  
  83.     {  
  84.         for(int j=0;j<m_ImageWidth*3;j=j+3)  
  85.         {  
  86.             int k=m_ImageWidth*i*3+j;  
  87.             int gray=(int)(0.3*m_imagedata[k]+0.59*m_imagedata[k+1]+0.11*m_imagedata[k+2]);  
  88.             m_outputdata[k]=m_outputdata[k+1]=m_outputdata[k+2]=gray;  
  89.         }  
  90.     }  
  91.     //創建新文件  
  92.     if((fp2=fopen("result.bmp","wb"))==NULL)  
  93.     {  
  94.         MessageBox(NULL,"文件創建失敗","warning",MB_OK);  
  95.     }  
  96.   
  97.     //寫結果文件,文件信息部分用test文件的文件信息部分  
  98.     fwrite((LPSTR)&bf,sizeof(BITMAPFILEHEADER),1,fp2);  
  99.     fwrite((LPSTR)&bi,sizeof(BITMAPINFOHEADER),1,fp2);  
  100.     fwrite(palette,bf.bfOffBits-sizeof(BITMAPFILEHEADER)-sizeof(BITMAPINFOHEADER),1,fp2);  
  101.     fwrite(m_outputdata,m_ImageHeight*m_ImageWidth*3,1,fp2); //寫像素數據  
  102.   
  103.     fclose(fp1);  //關閉文件  
  104.     fclose(fp2);  


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章