全局變量:
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 }