全局變量:
1 #include "stdafx.h" 2 #include <windows.h> 3 4 /*BMP位圖數據是4字節對齊*/ 5 #define WIDTHBYTES(bits) ((DWORD)(((bits)+31) & (~31)) / 8) 6 #define WIDTHBYTES(bits) ((DWORD)((((bits)+31) / 32) * 4) 7 8 unsigned char *gPBmpBuf ; //指向圖像數據的指針 9 int gBmpWidth ; //圖像的寬 10 int gBmpHeight; //圖像的高 11 RGBQUAD *gPColorTable ; //顏色表指針 12 int gBiBitCount; //圖像類型,每個像素的位數 13 char bmp[100] = "E:/test_pic.bmp"; 14 char saveBmp[100] = "E:/save_pic.bmp";
讀取bmp文件:
1 bool loadBmp(char *bmpName) 2 { 3 /*以二進制方式打開bmp文件*/ 4 FILE *fp = fopen(bmpName , "rb"); 5 if(NULL == fp) 6 { 7 printf("open file \"%s\" failed \n" , bmpName); 8 return false ; 9 } 10 11 /*跳過bmp文件結構體*/ 12 fseek(fp , sizeof(BITMAPFILEHEADER),0); 13 14 /*讀取bmp文件信息頭*/ 15 BITMAPINFOHEADER infoHead ; 16 fread(&infoHead , sizeof(BITMAPINFOHEADER),1 , fp); 17 18 /*獲取圖像寬,高,像素位數*/ 19 gBmpWidth = infoHead.biWidth ; 20 gBmpHeight = infoHead.biHeight; 21 gBiBitCount= infoHead.biBitCount; 22 23 /*獲取每行像素所占內存大小(必須為4的倍數)*/ 24 int lineByte = (gBmpWidth*gBiBitCount/8 + 3)/4*4 ; 25 26 /*灰度圖像有顏色表,且顏色表表項為256,24-位真彩色圖像就不使用彩色板*/ 27 if(8 == gBiBitCount) 28 { 29 gPColorTable = (RGBQUAD *)malloc(sizeof(RGBQUAD)*256); 30 fread(gPColorTable , sizeof(RGBQUAD) , 1 , fp); 31 } 32 33 /*申請位圖數據空間,並將位圖數據存放到內存*/ 34 gPBmpBuf = (unsigned char *)malloc(sizeof(unsigned char)*gBmpHeight*lineByte); 35 fread(gPBmpBuf,1 ,gBmpHeight*lineByte,fp); 36 37 fclose(fp); 38 39 return true ; 40 }
保存bmp文件格式:
1 bool storeBmp(char *bmpName , unsigned char *imgBuf , int width , int height, 2 int gBiBitCount , RGBQUAD *gPColorTable ) 3 { 4 /*對位圖數據進行判空操作*/ 5 if(NULL == imgBuf) 6 { 7 return false ; 8 } 9 10 /*根據像素位數,判斷當前顏色表大小*/ 11 int colorTableSize = 0 ; 12 if(gBiBitCount == 8) 13 { 14 /* 15 1字節用於藍色分量 16 1字節用於綠色分量 17 1字節用於紅色分量 18 1字節用於填充符(設置為0) 19 */ 20 colorTableSize = 1024 ; /*4*256*/ 21 } 22 23 /*待存儲圖像數據每行像素的大小(4的倍數)*/ 24 int lineByte = (gBmpWidth*gBiBitCount/8 + 3)/4*4 ; 25 26 FILE *fp = fopen(bmpName , "wb"); 27 if(NULL == fp) 28 { 29 printf("creat file failed !\n"); 30 return false ; 31 } 32 33 /*填寫位圖文件頭結構體*/ 34 BITMAPFILEHEADER fileHead ; 35 fileHead.bfType = 0x4D42 ; //bmp類型 36 fileHead.bfSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + 37 colorTableSize + lineByte*height ; 38 fileHead.bfReserved1 = 0 ; 39 fileHead.bfReserved2 = 0 ; 40 fileHead.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + 41 colorTableSize ; 42 fwrite(&fileHead , sizeof(BITMAPFILEHEADER),1 , fp); 43 44 /*填寫位圖信息結構體*/ 45 BITMAPINFOHEADER infoHead ; 46 infoHead.biBitCount = gBiBitCount ; 47 infoHead.biClrImportant = 0 ; 48 infoHead.biClrUsed = 0 ; 49 infoHead.biCompression = 0 ; 50 infoHead.biHeight = height ; 51 infoHead.biPlanes = 1 ; 52 infoHead.biSize = 40 ; 53 infoHead.biSizeImage = lineByte*height ; 54 infoHead.biWidth = width ; 55 infoHead.biXPelsPerMeter = 0 ; 56 infoHead.biYPelsPerMeter = 0 ; 57 fwrite(&infoHead , sizeof(BITMAPINFOHEADER),1 , fp); 58 59 /*填寫顏色表*/ 60 if(gBiBitCount == 8) 61 { 62 fwrite(&gPColorTable , sizeof(RGBQUAD),256 , fp); 63 } 64 65 /*寫位圖數據進文件*/ 66 fwrite( imgBuf, height * lineByte, 1, fp ); 67 68 fclose(fp); 69 70 return true ; 71 }
main入口測試:
1 int _tmain(int argc, _TCHAR* argv[]) 2 { 3 4 bool ret = false ; 5 6 ret |= loadBmp(bmp); 7 ret |= storeBmp(saveBmp,gPBmpBuf,gBmpWidth,gBmpHeight,gBiBitCount,gPColorTable); 8 9 if(false == ret) 10 { 11 printf("excut fail! \n"); 12 } 13 else if(true == ret) 14 { 15 printf("excut success!\n"); 16 } 17 18 if(gBiBitCount == 8) 19 { 20 free(gPColorTable); 21 } 22 23 free(gPBmpBuf); 24 25 return 0; 26 }