概述
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: %srnrn"), 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.rnrn"));
return;
}
dwFileSize = GetFileSize(hFile,&dwHighSize);
if(dwHighSize)
{//如果是大文件
Printf(hwnd, TEXT("Cannot deal with >4G files.rnrn"));
CloseHandle(hFile);
return;
}
pFile = (PBYTE)malloc(dwFileSize);
if(!pFile){
Printf(hwnd,TEXT("Cannot allocate memory.rnrn"));
CloseHandle(hFile);
return;
}
bSuccess = ReadFile(hFile,pFile,dwFileSize,&dwBytesRead,NULL);
if(!bSuccess)
{
Printf(hwnd, TEXT("Could not read file.rnrn"));
CloseHandle(hFile);
free(pFile);
return;
}
CloseHandle(hFile);
pbmfh = (BITMAPFILEHEADER *)pFile;
<span style="white-space:pre"> </span>//输出文件头信息
Printf(hwnd, TEXT("BITMAPFILEHEADERrn"));
Printf(hwnd, TEXT("t.bfType = 0x%Xrn"), pbmfh->bfType);
Printf(hwnd, TEXT("t.bfSize = %urn"), pbmfh->bfSize);
Printf(hwnd, TEXT("t.bfReserved1 = %urn"), pbmfh->bfReserved1);
Printf(hwnd, TEXT("t.bfReserved2 = %urn"), pbmfh->bfReserved2);
Printf(hwnd, TEXT("t.bfOffBits = %urnrn"), 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.rnrn"), pbmih->bV5Size);
free(pFile);
return;
}
Printf(hwnd, TEXT("%srn"), szInfoName[i]);
if(pbmih->bV5Size == sizeof(BITMAPCOREHEADER))
{
pbmch = (BITMAPCOREHEADER *)pbmih;
Printf(hwnd, TEXT("t.bcSize = %urn"), pbmch->bcSize);
Printf(hwnd, TEXT("t.bcWidth = %urn"), pbmch->bcWidth);
Printf(hwnd, TEXT("t.bcHeight = %urn"), pbmch->bcHeight);
Printf(hwnd, TEXT("t.bcPlanes = %urn"), pbmch->bcPlanes);
Printf(hwnd, TEXT("t.bcBitCount = %urn"), pbmch->bcBitCount);
free(pFile);
return;
}
Printf (hwnd, TEXT ("t.b%sSize = %urn"), szV, pbmih->bV5Size);
Printf (hwnd, TEXT ("t.b%sWidth = %irn"), szV, pbmih->bV5Width);
Printf (hwnd, TEXT ("t.b%sHeight = %irn"), szV, pbmih->bV5Height) ;
Printf (hwnd, TEXT ("t.b%sPlanes = %urn"), szV, pbmih->bV5Planes) ;
Printf (hwnd, TEXT ("t.b%sBitCount = %urn"), szV, pbmih->bV5BitCount) ;
Printf (hwnd, TEXT ("t.b%sCompression = %srn"), szV, szCompression [min (4, pbmih->bV5Compression)]) ;
Printf (hwnd, TEXT ("t.b%sSizeImage = %urn"), szV, pbmih->bV5SizeImage);
Printf (hwnd, TEXT ("t.b%sXPelsPerMeter = %irn"), szV, pbmih->bV5XPelsPerMeter) ;
Printf (hwnd, TEXT ("t.b%sYPelsPerMeter = %irn"), szV, pbmih->bV5YPelsPerMeter) ;
Printf (hwnd, TEXT ("t.b%sClrUsed = %irn"), szV, pbmih->bV5ClrUsed) ;
Printf (hwnd, TEXT ("t.b%sClrImportant = %irnrn"), szV, pbmih->bV5ClrImportant) ;
if(pbmih->bV5Size == sizeof(BITMAPINFOHEADER))
{
if(pbmih->bV5Compression == BI_BITFIELDS)
{
Printf(hwnd, TEXT("Red Mask = %08Xrn"), pbmih->bV5RedMask);
Printf(hwnd, TEXT("Green Mask = %08Xrn"), pbmih->bV5GreenMask);
Printf(hwnd, TEXT("Blue Mask = %08Xrnrn"), pbmih->bV5BlueMask);
}
free(pFile);
return;
}
Printf (hwnd, TEXT ("t.b%sRedMask = %08Xrn"), szV, pbmih->bV5RedMask);
Printf (hwnd, TEXT ("t.b%sGreenMask = %08Xrn"), szV, pbmih->bV5GreenMask) ;
Printf (hwnd, TEXT ("t.b%sBlueMask = %08Xrn"), szV, pbmih->bV5BlueMask) ;
Printf (hwnd, TEXT ("t.b%sAlphaMask = %08Xrn"), szV, pbmih->bV5AlphaMask) ;
Printf (hwnd, TEXT ("t.b%sCSType = %urn"), szV, pbmih->bV5CSType) ;
Printf (hwnd, TEXT ("t.b%sEndpoints.ciexyzRed.ciexyzX = %08Xrn"), szV, pbmih->bV5Endpoints.ciexyzRed.ciexyzX) ;
Printf (hwnd, TEXT ("t.b%sEndpoints.ciexyzRed.ciexyzY = %08Xrn"), szV, pbmih->bV5Endpoints.ciexyzRed.ciexyzY) ;
Printf (hwnd, TEXT ("t.b%sEndpoints.ciexyzRed.ciexyzZ = %08Xrn"), szV, pbmih->bV5Endpoints.ciexyzRed.ciexyzZ) ;
Printf (hwnd, TEXT ("t.b%sEndpoints.ciexyzGreen.ciexyzX = %08Xrn"), szV, pbmih->bV5Endpoints.ciexyzGreen.ciexyzX) ;
Printf (hwnd, TEXT ("t.b%sEndpoints.ciexyzGreen.ciexyzY = %08Xrn"), szV, pbmih->bV5Endpoints.ciexyzGreen.ciexyzY) ;
Printf (hwnd, TEXT ("t.b%sEndpoints.ciexyzGreen.ciexyzZ = %08Xrn"), szV, pbmih->bV5Endpoints.ciexyzGreen.ciexyzZ) ;
Printf (hwnd, TEXT ("t.b%sEndpoints.ciexyzBlue.ciexyzX = %08Xrn"), szV, pbmih->bV5Endpoints.ciexyzBlue.ciexyzX) ;
Printf (hwnd, TEXT ("t.b%sEndpoints.ciexyzBlue.ciexyzY = %08Xrn"), szV, pbmih->bV5Endpoints.ciexyzBlue.ciexyzY) ;
Printf (hwnd, TEXT ("t.b%sEndpoints.ciexyzBlue.ciexyzZ = %08Xrn"), szV, pbmih->bV5Endpoints.ciexyzBlue.ciexyzZ) ;
Printf (hwnd, TEXT ("t.b%sGammaRed = %08Xrn"), szV, pbmih->bV5GammaRed) ;
Printf (hwnd, TEXT ("t.b%sGammaGreen = %08Xrn"), szV, pbmih->bV5GammaGreen) ;
Printf (hwnd, TEXT ("t.b%sGammaBlue = %08Xrnrn"), szV, pbmih->bV5GammaBlue) ;
if(pbmih->bV5Size == sizeof(BITMAPV4HEADER))
{
free(pFile);
return;
}
Printf (hwnd, TEXT ("t.b%sIntent = %urn"), szV, pbmih->bV5Intent);
Printf (hwnd, TEXT ("t.b%sProfileData = %urn"), szV, pbmih->bV5ProfileData) ;
Printf (hwnd, TEXT ("t.b%sProfileSize = %urn"), szV, pbmih->bV5ProfileSize) ;
Printf (hwnd, TEXT ("t.b%sReserved = %urnrn"), szV, pbmih->bV5Reserved) ;
free(pFile);
return;
}
下面显示了如何显示一个BMP文件
<pre name="code" class="cpp">void DibFileInitialize(HWND hwnd)
{//初始化一个OPENFILE结构
static TCHAR szFilter[] = TEXT("BitmapFile(*.bmp) *.bmp ")
TEXT("All Files(*.*) *.* ");
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;
}
最后
以上就是文静咖啡豆为你收集整理的bmp/dib文件的格式的全部内容,希望文章能够帮你解决bmp/dib文件的格式所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复