天天看點

C語言編寫的bmp讀寫程式

C語言編寫的bmp讀寫程式 建議先把bmp的資料存儲格式了解下 

<span style="font-size:16px;">#include "Windows.h"  

#include "stdio.h"  

#include "string.h"  

#include "malloc.h"  

unsigned char *pBmpBuf;//讀入圖像資料的指針  

int bmpWidth;//圖像的寬  

int bmpHeight;//圖像的高  

RGBQUAD *pColorTable;//顔色表指針  

int biBitCount;//圖像類型,每像素位數  

bool readBmp(char *bmpName)  

{  

  //二進制讀方式打開指定的圖像檔案  

  FILE *fp=fopen(bmpName,"rb");  

  if(fp==0) return 0;  

  //跳過位圖檔案頭結構BITMAPFILEHEADER  

  fseek(fp, sizeof(BITMAPFILEHEADER),0);  

  //定義位圖資訊頭結構變量,讀取位圖資訊頭進記憶體,存放在變量head中  

  BITMAPINFOHEADER head;     

  fread(&head, sizeof(BITMAPINFOHEADER), 1,fp);    

  //擷取圖像寬、高、每像素所占位數等資訊  

  bmpWidth = head.biWidth;  

  bmpHeight = head.biHeight;  

  biBitCount = head.biBitCount;  

  //定義變量,計算圖像每行像素所占的位元組數(必須是4的倍數)  

  int lineByte=(bmpWidth * biBitCount/8+3)/4*4;  

  //灰階圖像有顔色表,且顔色表表項為256  

  if(biBitCount==8){  

  //申請顔色表所需要的空間,讀顔色表進記憶體  

  pColorTable=new RGBQUAD[256];  

  fread(pColorTable,sizeof(RGBQUAD),256,fp);  

  }  

  //申請位圖資料所需要的空間,讀位圖資料進記憶體  

  pBmpBuf=new unsigned char[lineByte * bmpHeight];  

  fread(pBmpBuf,1,lineByte * bmpHeight,fp);  

  //關閉檔案  

  fclose(fp);  

  return 1;  

}  

bool saveBmp(char *bmpName, unsigned char *imgBuf, int width, int height,    

  int biBitCount, RGBQUAD *pColorTable)  

  //如果位圖資料指針為0,則沒有資料傳入,函數傳回  

  if(!imgBuf)  

  return 0;  

  //顔色表大小,以位元組為機關,灰階圖像顔色表為1024位元組,彩色圖像顔色表大小為0  

  int colorTablesize=0;  

  if(biBitCount==8)  

  colorTablesize=1024;  

  //待存儲圖像資料每行位元組數為4的倍數  

  int lineByte=(width * biBitCount/8+3)/4*4;  

  //以二進制寫的方式打開檔案  

  FILE *fp=fopen(bmpName,"wb");  

  //申請位圖檔案頭結構變量,填寫檔案頭資訊  

  BITMAPFILEHEADER fileHead;  

  fileHead.bfType = 0x4D42;//bmp類型  

  //bfSize是圖像檔案4個組成部分之和  

  fileHead.bfSize= sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER)  

  + colorTablesize + lineByte*height;  

  fileHead.bfReserved1 = 0;  

  fileHead.bfReserved2 = 0;  

  //bfOffBits是圖像檔案前3個部分所需空間之和  

  fileHead.bfOffBits=54+colorTablesize;  

  //寫檔案頭進檔案  

  fwrite(&fileHead, sizeof(BITMAPFILEHEADER),1, fp);  

  //申請位圖資訊頭結構變量,填寫資訊頭資訊  

  BITMAPINFOHEADER head;    

  head.biBitCount=biBitCount;  

  head.biClrImportant=0;  

  head.biClrUsed=0;  

  head.biCompression=0;  

  head.biHeight=height;  

  head.biPlanes=1;  

  head.biSize=40;  

  head.biSizeImage=lineByte*height;  

  head.biWidth=width;  

  head.biXPelsPerMeter=0;  

  head.biYPelsPerMeter=0;  

  //寫位圖資訊頭進記憶體  

  fwrite(&head, sizeof(BITMAPINFOHEADER),1, fp);  

  //如果灰階圖像,有顔色表,寫入檔案    

  fwrite(pColorTable, sizeof(RGBQUAD),256, fp);  

  //寫位圖資料進檔案  

  fwrite(imgBuf, height*lineByte, 1, fp);  

void main()  

  char inFileName[90],outFileName[90];  

printf("請輸入原始位圖檔案的檔案名:");  

  scanf("%s",inFileName);  

  printf("請輸入加密程式産生的新位圖檔案的檔案名:");  

  scanf("%s",outFileName);  

//讀入指定BMP檔案進記憶體  

  readBmp(inFileName);  

  //輸出圖像的資訊  

  printf("width=%d,height=%d, biBitCount=%d\n",bmpWidth,bmpHeight, biBitCount);  

  //将圖像資料存盤  

  saveBmp(outFileName, pBmpBuf, bmpWidth, bmpHeight, biBitCount, pColorTable);  

  //清除緩沖區,pBmpBuf和pColorTable是全局變量,在檔案讀入時申請的空間  

  delete []pBmpBuf;  

  delete []pColorTable;  

</span>  

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

一、BMP檔案結構 

BMP檔案組成 

BMP檔案由檔案頭、位圖資訊頭、顔色資訊和圖形資料四部分組成。   

BMP檔案頭 

BMP檔案頭資料結構含有BMP檔案的類型、檔案大小和位圖起始位置等資訊。   

其結構定義如下: 

typedef   struct   tagBITMAPFILEHEADER 

WORDbfType;   //   位圖檔案的類型,必須為BM 

DWORD   bfSize;   //   位圖檔案的大小,以位元組為機關   

WORDbfReserved1;   //   位圖檔案保留字,必須為0 

WORDbfReserved2;   //   位圖檔案保留字,必須為0 

DWORD   bfOffBits;   //   位圖資料的起始位置,以相對于位圖 

//   檔案頭的偏移量表示,以位元組為機關 

}   BITMAPFILEHEADER; 

3.   位圖資訊頭 

BMP位圖資訊頭資料用于說明位圖的尺寸等資訊。 

typedef   struct   tagBITMAPINFOHEADER{ 

DWORD   biSize;   //   本結構所占用位元組數 

LONGbiWidth;   //   位圖的寬度,以像素為機關 

LONGbiHeight;   //   位圖的高度,以像素為機關 

WORD   biPlanes;   //   目标裝置的級别,必須為1 

WORD   biBitCount//   每個像素所需的位數,必須是1(雙色), 

//   4(16色),8(256色)或24(真彩色)之一 

DWORD   biCompression;   //   位圖壓縮類型,必須是   0(不壓縮), 

//   1(BI_RLE8壓縮類型)或2(BI_RLE4壓縮類型)之一 

DWORD   biSizeImage;   //   位圖的大小,以位元組為機關 

LONGbiXPelsPerMeter;   //   位圖水準分辨率,每米像素數 

LONGbiYPelsPerMeter;   //   位圖垂直分辨率,每米像素數 

DWORD   biClrUsed;//   位圖實際使用的顔色表中的顔色數 

DWORD   biClrImportant;//   位圖顯示過程中重要的顔色數 

}   BITMAPINFOHEADER; 

4.   顔色表 

  顔色表用于說明位圖中的顔色,它有若幹個表項,每一個表項是一個RGBQUAD類型的結構,定義一種顔色。RGBQUAD結構的定義如下: 

typedef   struct   tagRGBQUAD   { 

BYTErgbBlue;//   藍色的亮度(值範圍為0-255) 

BYTErgbGreen;   //   綠色的亮度(值範圍為0-255) 

BYTErgbRed;   //   紅色的亮度(值範圍為0-255) 

BYTErgbReserved;//   保留,必須為0 

}   RGBQUAD; 

顔色表中RGBQUAD結構資料的個數有biBitCount來确定: 

當biBitCount=1,4,8時,分别有2,16,256個表項; 

當biBitCount=24時,沒有顔色表項。 

位圖資訊頭和顔色表組成位圖資訊,BITMAPINFO結構定義如下: 

typedef   struct   tagBITMAPINFO   { 

BITMAPINFOHEADER   bmiHeader;   //   位圖資訊頭 

RGBQUAD   bmiColors[1];   //   顔色表 

}   BITMAPINFO; 

5.   位圖資料 

  位圖資料記錄了位圖的每一個像素值,記錄順序是在掃描行内是從左到右,掃描行之間是從下到上。位圖的一個像素值所占的位元組數: 

當biBitCount=1時,8個像素占1個位元組; 

當biBitCount=4時,2個像素占1個位元組; 

當biBitCount=8時,1個像素占1個位元組; 

當biBitCount=24時,1個像素占3個位元組; 

Windows規定一個掃描行所占的位元組數必須是 

4的倍數(即以long為機關),不足的以0填充, 

一個掃描行所占的位元組數計算方法: 

DataSizePerLine=   (biWidth*   biBitCount+31)/8;   

//   一個掃描行所占的位元組數 

DataSizePerLine=   DataSizePerLine/4*4;   //   位元組數必須是4的倍數 

位圖資料的大小(不壓縮情況下): 

DataSize=   DataSizePerLine*   biHeight; 

繼續閱讀