bmp/dib文件的格式

来源:互联网 发布:网站用php与asp哪个好 编辑:程序博客网 时间:2024/05/17 01:03

Bmp又叫dib文件

任何一个bmp文件都包含这四个信息

『文件头 / 信息头 / 颜色表 / 像素位』

1.文件头: 

文件头个14个字节的结构体

struct tagBITMAPFILEHEADER

{

       WORD bfType;       

       DWORD bfSize;

       WORD      bfReserved1;

       WORD bfReserved2;

       DWORDbfOffsetBits;

};


bfType 表示文件签名   即”BM”两个字母  也就是16进制的0X4D42

bfSize 表示该图片文件的大小

bfReserved1;    一般不用,值为0

bfReserved2;     一般不用,值为0

bfOffsetBits;    表示从文件头到像素位的偏移,这个比较重要、、

2.信息头:

信息头随着时代的不同,有四种版本的信息头:

1.tagBITMAPCOREHEADER版本

————————————————————

typedef struct tagBITMAPCOREHEADER {

       DWORD   bcSize;          //结构的大小 = 12

       WORD    bcWidth;

       WORD    bcHeight;

       WORD    bcPlanes;

       WORD    bcBitCount;

} BITMAPCOREHEADER;

2.tagBITMAPINFOHEADER版本

 ————————————————————

typedef struct tagBITMAPINFOHEADER{

       DWORD      biSize;    //结构的大小 = 40

       LONG       biWidth;

       LONG       biHeight;

       WORD       biPlanes;

       WORD       biBitCount;

       DWORD      biCompression;

       DWORD      biSizeImage;

       LONG       biXPelsPerMeter;

       LONG       biYPelsPerMeter;

       DWORD      biClrUsed;

       DWORD      biClrImportant;

} BITMAPINFOHEADER;

3.BITMAPV4HEADER版本

————————————————————

typedef struct {

       DWORD        bV4Size;    //结构的大小 = 108

       LONG         bV4Width;

       LONG         bV4Height;

        WORD        bV4Planes;

       WORD         bV4BitCount;

       DWORD        bV4V4Compression;

       DWORD        bV4SizeImage;

       LONG         bV4XPelsPerMeter;

       LONG         bV4YPelsPerMeter;

       DWORD        bV4ClrUsed;

       DWORD        bV4ClrImportant;

        …

       CIEXYZTRIPLE bV4Endpoints;

       DWORD        bV4GammaRed;

       DWORD        bV4GammaGreen;

       DWORD        bV4GammaBlue;

} BITMAPV4HEADER;

4.BITMAPV5HEADER版本 

——————————————————————

 typedef struct {

       DWORD        bV5Size;    //结构的大小 = 124

       LONG         bV5Width;

       LONG         bV5Height;

       WORD         bV5Planes;

       WORD         bV5BitCount;

       DWORD        bV5Compression;

       DWORD        bV5SizeImage;

       LONG         bV5XPelsPerMeter;

       LONG         bV5YPelsPerMeter;

       DWORD        bV5ClrUsed;

       DWORD        bV5ClrImportant;

           …

           …

       DWORD        bV5ProfileData;

       DWORD        bV5ProfileSize;

       DWORD        bV5Reserved;

} BITMAPV5HEADER

——————————————

后面的版本是前面版本的扩充,包括以前版本的字段:

其中有一些字段是比较重要的:(就以tagBITMAPCOREHEADER类型为例,其他只是名字不同

DWORD  bcSize;          //结构的大小,

WORD   bcWidth;                 //图片的宽度

WORD   bcHeight;                //图片的高度

WORD   bcPlanes;                

WORD   bcBitCount;            //颜色为数量


一般读取信息头的时候把变量定义成版本BITMAPV5HEADER,因为我们不能确定所读取的文件信息头是那个版本的信息头,而V5 的信息头结构最大,字段最多,包括了其他版本的信息头的字段,所以我们用最大的去读,然后通过其中bV5Size这个字段得知该信息头的大小,而每种版本的信息头大小恰好不同!!!,这样就确定他是那种信息头

void DisplayDibHeaders(HWND hwnd, TCHAR *szFileName){//显示一个位图的信息,其中Printf为一个自定义函数static TCHAR *szInfoName[] = {TEXT("BITMAPCOREHEADER"),TEXT("BITMAPINFOHEADER"),TEXT("BITMAPV4HEADER"),TEXT("BITMAPV5HEADER")};static TCHAR *szCompression[] = {TEXT("BI_RGB"),TEXT("BI_RLE8"),TEXT("BI_RLE4"),TEXT("BI_BITFIELDS"),TEXT("unknown")};HANDLE hFile;DWORD dwFileSize, dwHighSize, dwBytesRead;PBYTE pFile;BOOL bSuccess;BITMAPFILEHEADER *pbmfh;BITMAPV5HEADER *pbmih;BITMAPCOREHEADER *pbmch;int i;TCHAR *szV;Printf(hwnd, TEXT("File: %s\r\n\r\n"), szFileName);//打开文件,读文件hFile = CreateFile(szFileName, GENERIC_READ,FILE_SHARE_READ,0,OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN,NULL);if(hFile == INVALID_HANDLE_VALUE){Printf(hwnd, TEXT("Cannot open file.\r\n\rn"));return;}dwFileSize = GetFileSize(hFile,&dwHighSize);if(dwHighSize){//如果是大文件Printf(hwnd, TEXT("Cannot deal with >4G files.\r\n\r\n"));CloseHandle(hFile);return;}pFile = (PBYTE)malloc(dwFileSize);if(!pFile){Printf(hwnd,TEXT("Cannot allocate memory.\r\n\r\n"));CloseHandle(hFile);return;}bSuccess = ReadFile(hFile,pFile,dwFileSize,&dwBytesRead,NULL);if(!bSuccess){Printf(hwnd, TEXT("Could not read file.\r\n\r\n"));CloseHandle(hFile);free(pFile);return;}CloseHandle(hFile);pbmfh = (BITMAPFILEHEADER *)pFile;<span style="white-space:pre"></span>//输出文件头信息Printf(hwnd, TEXT("BITMAPFILEHEADER\r\n"));Printf(hwnd, TEXT("\t.bfType = 0x%X\r\n"), pbmfh->bfType);Printf(hwnd, TEXT("\t.bfSize = %u\r\n"), pbmfh->bfSize);Printf(hwnd, TEXT("\t.bfReserved1 = %u\r\n"), pbmfh->bfReserved1);Printf(hwnd, TEXT("\t.bfReserved2 = %u\r\n"), pbmfh->bfReserved2);Printf(hwnd, TEXT("\t.bfOffBits = %u\r\n\r\n"), pbmfh->bfOffBits);<span style="white-space:pre"></span>pbmih = (BITMAPV5HEADER *)(pFile + sizeof(BITMAPFILEHEADER));<span style="white-space:pre"></span>//以最大的版本去读switch(pbmih->bV5Size){case sizeof(BITMAPCOREHEADER): i = 0;break;case sizeof(BITMAPINFOHEADER):i = 1;szV = TEXT("i");break;case sizeof(BITMAPV4HEADER):i = 2;szV = TEXT("V4");break;case sizeof(BITMAPV5HEADER):i = 3;szV = TEXT("V5");break;default:Printf(hwnd, TEXT("Unknown header size of %u.\r\n\r\n"), pbmih->bV5Size);free(pFile);return;}Printf(hwnd, TEXT("%s\r\n"), szInfoName[i]);if(pbmih->bV5Size == sizeof(BITMAPCOREHEADER)){pbmch = (BITMAPCOREHEADER *)pbmih;Printf(hwnd, TEXT("\t.bcSize = %u\r\n"), pbmch->bcSize);Printf(hwnd, TEXT("\t.bcWidth = %u\r\n"), pbmch->bcWidth);Printf(hwnd, TEXT("\t.bcHeight = %u\r\n"), pbmch->bcHeight);Printf(hwnd, TEXT("\t.bcPlanes = %u\r\n"), pbmch->bcPlanes);Printf(hwnd, TEXT("\t.bcBitCount = %u\r\n"), pbmch->bcBitCount);free(pFile);return;}Printf (hwnd, TEXT ("\t.b%sSize = %u\r\n"), szV, pbmih->bV5Size);Printf (hwnd, TEXT ("\t.b%sWidth = %i\r\n"), szV, pbmih->bV5Width);Printf (hwnd, TEXT ("\t.b%sHeight = %i\r\n"), szV, pbmih->bV5Height) ;Printf (hwnd, TEXT ("\t.b%sPlanes = %u\r\n"), szV, pbmih->bV5Planes) ;Printf (hwnd, TEXT ("\t.b%sBitCount = %u\r\n"), szV, pbmih->bV5BitCount) ;Printf (hwnd, TEXT ("\t.b%sCompression = %s\r\n"), szV, szCompression [min (4, pbmih->bV5Compression)]) ;Printf (hwnd, TEXT ("\t.b%sSizeImage = %u\r\n"), szV, pbmih->bV5SizeImage);Printf (hwnd, TEXT ("\t.b%sXPelsPerMeter = %i\r\n"), szV, pbmih->bV5XPelsPerMeter) ;Printf (hwnd, TEXT ("\t.b%sYPelsPerMeter = %i\r\n"), szV, pbmih->bV5YPelsPerMeter) ;Printf (hwnd, TEXT ("\t.b%sClrUsed = %i\r\n"), szV, pbmih->bV5ClrUsed) ;Printf (hwnd, TEXT ("\t.b%sClrImportant = %i\r\n\r\n"), szV, pbmih->bV5ClrImportant) ;if(pbmih->bV5Size == sizeof(BITMAPINFOHEADER)){if(pbmih->bV5Compression == BI_BITFIELDS){Printf(hwnd, TEXT("Red Mask = %08X\r\n"), pbmih->bV5RedMask);Printf(hwnd, TEXT("Green Mask = %08X\r\n"), pbmih->bV5GreenMask);Printf(hwnd, TEXT("Blue Mask = %08X\r\n\r\n"), pbmih->bV5BlueMask);}free(pFile);return;}Printf (hwnd, TEXT ("\t.b%sRedMask = %08X\r\n"), szV, pbmih->bV5RedMask);Printf (hwnd, TEXT ("\t.b%sGreenMask = %08X\r\n"), szV, pbmih->bV5GreenMask) ;Printf (hwnd, TEXT ("\t.b%sBlueMask  = %08X\r\n"), szV, pbmih->bV5BlueMask) ;Printf (hwnd, TEXT ("\t.b%sAlphaMask = %08X\r\n"), szV, pbmih->bV5AlphaMask) ;Printf (hwnd, TEXT ("\t.b%sCSType = %u\r\n"), szV, pbmih->bV5CSType) ;Printf (hwnd, TEXT ("\t.b%sEndpoints.ciexyzRed.ciexyzX   = %08X\r\n"), szV, pbmih->bV5Endpoints.ciexyzRed.ciexyzX) ;Printf (hwnd, TEXT ("\t.b%sEndpoints.ciexyzRed.ciexyzY   = %08X\r\n"), szV, pbmih->bV5Endpoints.ciexyzRed.ciexyzY) ;Printf (hwnd, TEXT ("\t.b%sEndpoints.ciexyzRed.ciexyzZ   = %08X\r\n"), szV, pbmih->bV5Endpoints.ciexyzRed.ciexyzZ) ;Printf (hwnd, TEXT ("\t.b%sEndpoints.ciexyzGreen.ciexyzX = %08X\r\n"), szV, pbmih->bV5Endpoints.ciexyzGreen.ciexyzX) ;Printf (hwnd, TEXT ("\t.b%sEndpoints.ciexyzGreen.ciexyzY = %08X\r\n"), szV, pbmih->bV5Endpoints.ciexyzGreen.ciexyzY) ;Printf (hwnd, TEXT ("\t.b%sEndpoints.ciexyzGreen.ciexyzZ = %08X\r\n"), szV, pbmih->bV5Endpoints.ciexyzGreen.ciexyzZ) ;Printf (hwnd, TEXT ("\t.b%sEndpoints.ciexyzBlue.ciexyzX  = %08X\r\n"), szV, pbmih->bV5Endpoints.ciexyzBlue.ciexyzX) ;Printf (hwnd, TEXT ("\t.b%sEndpoints.ciexyzBlue.ciexyzY  = %08X\r\n"), szV, pbmih->bV5Endpoints.ciexyzBlue.ciexyzY) ;Printf (hwnd, TEXT ("\t.b%sEndpoints.ciexyzBlue.ciexyzZ  = %08X\r\n"), szV, pbmih->bV5Endpoints.ciexyzBlue.ciexyzZ) ;Printf (hwnd, TEXT ("\t.b%sGammaRed   = %08X\r\n"), szV, pbmih->bV5GammaRed) ;Printf (hwnd, TEXT ("\t.b%sGammaGreen = %08X\r\n"), szV, pbmih->bV5GammaGreen) ;Printf (hwnd, TEXT ("\t.b%sGammaBlue  = %08X\r\n\r\n"), szV, pbmih->bV5GammaBlue) ;if(pbmih->bV5Size == sizeof(BITMAPV4HEADER)){free(pFile);return;}Printf (hwnd, TEXT ("\t.b%sIntent = %u\r\n"), szV, pbmih->bV5Intent);Printf (hwnd, TEXT ("\t.b%sProfileData = %u\r\n"), szV, pbmih->bV5ProfileData) ;Printf (hwnd, TEXT ("\t.b%sProfileSize = %u\r\n"), szV, pbmih->bV5ProfileSize) ;Printf (hwnd, TEXT ("\t.b%sReserved = %u\r\n\r\n"), szV, pbmih->bV5Reserved) ;free(pFile);return;}
下面显示了如何显示一个BMP文件

<pre name="code" class="cpp">void DibFileInitialize(HWND hwnd){//初始化一个OPENFILE结构static TCHAR szFilter[] =  TEXT("BitmapFile(*.bmp)\0*.bmp\0")TEXT("All Files(*.*)\0*.*\0\0");ofn.lStructSize = sizeof(OPENFILENAME);ofn.hwndOwner = hwnd;ofn.hInstance = NULL;ofn.lpstrFilter = szFilter;ofn.lpstrCustomFilter = NULL;ofn.nMaxCustFilter = 0;ofn.nFilterIndex = 0;ofn.lpstrFile = NULL;ofn.nMaxFile = MAX_PATH;ofn.lpstrFileTitle = NULL;ofn.nMaxFileTitle = MAX_PATH;ofn.lpstrInitialDir = NULL;ofn.lpstrTitle = NULL;ofn.Flags = 0;ofn.nFileOffset = 0;ofn.nFileExtension = 0;ofn.lpstrDefExt = TEXT("bmp");ofn.lCustData = 0;ofn.lpfnHook = NULL;ofn.lpTemplateName = NULL;}BOOL DibFileOpenDlg(HWND hwnd, PTSTR pstrFileName, PTSTR pstrTitleName){ofn.hwndOwner = hwnd;ofn.lpstrFile = pstrFileName;ofn.lpstrFileTitle = pstrTitleName;ofn.Flags = 0;return GetOpenFileName(&ofn);}BITMAPFILEHEADER* DibLoadImage(PTSTR pstrFileName){BOOL bSuccess;DWORD dwFileSize, dwHighSize, dwBytesRead;HANDLE hFile;BITMAPFILEHEADER * pbmfh;hFile = CreateFile(pstrFileName, GENERIC_READ, FILE_SHARE_READ, NULL,OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL);if (hFile == INVALID_HANDLE_VALUE)return NULL;dwFileSize = GetFileSize(hFile, &dwHighSize);if (dwHighSize){CloseHandle(hFile);return NULL;}pbmfh = (BITMAPFILEHEADER*)malloc(dwFileSize);if (!pbmfh){CloseHandle(hFile);return NULL;}bSuccess = ReadFile(hFile, pbmfh, dwFileSize, &dwBytesRead, NULL);CloseHandle(hFile);if (!bSuccess || (dwBytesRead != dwFileSize)|| (pbmfh->bfType != *(WORD*)"BM")|| (pbmfh->bfSize != dwFileSize)){free(pbmfh);return NULL;}return pbmfh;}

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam){static BITMAPFILEHEADER* pbmfh;int wmId, wmEvent;PAINTSTRUCT ps;HDC hdc;static TCHAR szFileName[MAX_PATH], szTitleName[MAX_PATH];static BITMAPINFO* pbmi;static BYTE* pBits;static int cxDib, cyDib;switch (message){case WM_CREATE:DibFileInitialize(hWnd);return 0;case WM_COMMAND:wmId    = LOWORD(wParam);wmEvent = HIWORD(wParam);// 分析菜单选择: switch (wmId){case IDM_OPEN:if (!DibFileOpenDlg(hWnd, szFileName, szTitleName))return 0;if (pbmfh){free(pbmfh);pbmfh = NULL;}pbmfh = DibLoadImage(szFileName);InvalidateRect(hWnd, NULL, TRUE);pbmi = (BITMAPINFO*)(pbmfh + 1);pBits = (BYTE*)pbmfh + pbmfh->bfOffBits;if (pbmi->bmiHeader.biSize == sizeof(BITMAPCOREINFO)){cxDib = ((BITMAPCOREHEADER*)pbmi)->bcWidth;cyDib = ((BITMAPCOREHEADER*)pbmi)->bcHeight;}else{cxDib = pbmi->bmiHeader.biWidth;cyDib = abs(pbmi->bmiHeader.biHeight);}break;default:return DefWindowProc(hWnd, message, wParam, lParam);}break;case WM_PAINT:hdc = BeginPaint(hWnd, &ps);// TODO:  在此添加任意绘图代码...if (pbmfh)SetDIBitsToDevice(hdc, 100, 50, cxDib, cyDib, 0, 0, 0, cyDib, pBits, pbmi, DIB_RGB_COLORS);EndPaint(hWnd, &ps);break;case WM_DESTROY:if (pbmfh)free(pbmfh);PostQuitMessage(0);break;default:return DefWindowProc(hWnd, message, wParam, lParam);}return 0;}





0 0
原创粉丝点击