C++實現bmp格式圖像讀寫

bmp格式圖像有一個特點就是這類數據被分為四個部分:

1.位圖文件頭(Bitmap File Header) ,大小:14字節

主要包括位圖文件大小和位圖文件類型信息

2.位圖信息頭(Bitmap Info Header),大小:40字節

主要包括:位圖的寬度和高度,像素為單位、每個像素所占位數(1黑白圖像),(4-16色圖)、(8-256色圖)、(24-真彩色圖),新的BMP格式可以支持32位色。 還有其它水平和垂直分辨力(單位:像素/米)等  

3.顏色表(Color Map),大小:4個字節

三大類:藍色分量、綠色分量、紅色分量

4.位圖數據(Data Body)

對於2色位圖用1位就可以表示該像素,那麼1個字節就可以儲存8個像素的顏色值

對於16色位圖,用4個字節表示一個像素顏色,那麼一個字節可以儲存2個像素顏色值

對於256色位圖,1個字節剛好儲存1個像素的顏色值

對於真彩色位圖,則需要3個字節才能表示一個像素的顏色值

1.讀bmp圖像

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;
}

2.寫bmp圖像

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");
 if(fp==0) return 0;
 
 //申請位圖文件頭結構變量,填寫文件頭信息
 BITMAPFILEHEADER fileHead;
 fileHead.bfType = 0x4D42;//bmp類型
 
 //bfSize是圖像文件4個組成部分之和
 fileHead.bfSize= sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER)
  + colorTablesize + lineByte*height;
 fileHead.bfReserved1 = 0;
 fileHead.bfReserved2 = 0;
 
 //bfOffBits是圖像文件前三個部分所需空間之和
 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);
 
 //如果灰度圖像,有顏色表,寫入文件 
 if(biBitCount==8)
  fwrite(pColorTable, sizeof(RGBQUAD),256, fp);
 
 //寫位圖數據進文件
 fwrite(imgBuf, height*lineByte, 1, fp);
 
 //關閉文件
 fclose(fp);
 
 return 1;
}

以上就是本文的全部內容,希望對大傢的學習有所幫助,也希望大傢多多支持WalkonNet。

推薦閱讀: