BITMAPFILEHEADER bmfHeader;
DWORD dwBitsSize;
HANDLE hDIBtmp; // Used for GlobalRealloc() //MPB
LPBITMAPINFOHEADER lpbi;
DWORD offBits;
DWORD dwRead;
// get length of DIB in bytes for use when reading
dwBitsSize = pFile->GetLength();
// Allocate memory for header & color table. We'll enlarge this
// memory as needed.
m_hDIB = GlobalAlloc(GMEM_MOVEABLE, (DWORD)(sizeof(BITMAPINFOHEADER) +
256 * sizeof(RGBQUAD)));
if (!m_hDIB)
return FALSE;
lpbi = (LPBITMAPINFOHEADER)GlobalLock(m_hDIB);
if (!lpbi)
{
GlobalFree(m_hDIB);
return FALSE;
}
if (!ReadFile(pFile->m_hFile, (LPBYTE)lpbi, sizeof(BITMAPINFOHEADER), &dwRead,
NULL))
{
GlobalFree(m_hDIB);
return FALSE;
}
if (sizeof(BITMAPINFOHEADER) != dwRead)
{
GlobalFree(m_hDIB);
return FALSE;
}
if (lpbi->biSize == sizeof(BITMAPCOREHEADER))
{
GlobalFree(m_hDIB);
return FALSE; } lpbi->biBitCount = 8;
lpbi->biClrImportant = 256;
lpbi->biClrUsed = 256;
lpbi->biCompression = BI_RGB;
lpbi->biHeight = 600;
lpbi->biWidth = 600;
lpbi->biPlanes = 1;
lpbi->biSize = sizeof(BITMAPINFOHEADER);
lpbi->biSizeImage = 0;
lpbi->biXPelsPerMeter = 0;
lpbi->biYPelsPerMeter = 0; m_nColorNum = 256; // get a proper-sized buffer for header, color table and bits
GlobalUnlock(m_hDIB);
hDIBtmp = GlobalReAlloc(m_hDIB, lpbi->biSize + m_nColorNum *
sizeof(RGBQUAD) + lpbi->biSizeImage, 0);
if (!hDIBtmp) // can't resize buffer for loading
return FALSE;
else
m_hDIB = hDIBtmp;
lpbi = (LPBITMAPINFOHEADER)GlobalLock(m_hDIB);
offBits = lpbi->biSize + m_nColorNum * sizeof(RGBQUAD);
if (!ReadFile(pFile->m_hFile, (LPBYTE)lpbi + offBits, lpbi->biSizeImage, &dwRead,
NULL))
return FALSE;
GlobalUnlock(m_hDIB);
return TRUE;
/////////////////////////////////////////////////////////////////make palette
HPALETTE CBitmapShowDoc::CreateDIBPalette(LPBYTE lpbi)
{
LPLOGPALETTE lpPal; // pointer to a logical palette
HANDLE hLogPal; // handle to a logical palette
HPALETTE hPal = NULL;// handle to a palette
int i, wNumColors; // loop index, number of colors in color table
LPBITMAPINFO lpbmi; // pointer to BITMAPINFO structure (Win3.0)
LPBITMAPCOREINFO lpbmc; // pointer to BITMAPCOREINFO structure (OS/2)
// if handle to DIB is invalid, return NULL
if (! lpbi)
return NULL;
// get pointer to BITMAPINFO (Win 3.0)
lpbmi = (LPBITMAPINFO)lpbi;
// get pointer to BITMAPCOREINFO (OS/2 1.x)
wNumColors = m_nColorNum;
// is this a Win 3.0 DIB?
if (wNumColors)
{
// allocate memory block for logical palette
hLogPal = GlobalAlloc(GHND, sizeof(LOGPALETTE) +
sizeof(PALETTEENTRY) * wNumColors);
// if not enough memory, clean up and return NULL
if (!hLogPal)
return NULL;
// lock memory block and get pointer to it
lpPal = (LPLOGPALETTE)GlobalLock(hLogPal);
// set version and number of palette entries
lpPal->palVersion = 0x300;
lpPal->palNumEntries = wNumColors;
// store RGB triples (if Win 3.0 DIB) or RGB quads (if OS/2 DIB)
// into palette
for (i = 0; i < wNumColors; i++)
{
int j;
j = i*3;
lpPal->palPalEntry[i].peRed = j;//lpbmi->bmiColors[i].rgbRed;
lpPal->palPalEntry[i].peGreen = j;//lpbmi->bmiColors[i].rgbGreen;
lpPal->palPalEntry[i].peBlue = j;//lpbmi->bmiColors[i].rgbBlue;
lpPal->palPalEntry[i].peFlags = 0;
}
// create the palette and get handle to it
hPal = CreatePalette(lpPal);
// if error getting handle to palette, clean up and return NULL
if (!hPal)
{
GlobalUnlock(hLogPal);
GlobalFree(hLogPal);
return NULL;
}
}
// return handle to DIB's palette
return hPal;
///////////////////////////////////////////////////////////show image
BOOL CBitmapShowView::PaintDIB(HDC hDC, HANDLE hDIB, HPALETTE hPal, int colorNum)
{
LPBYTE lpDIBHdr; // Pointer to BITMAPINFOHEADER
LPBYTE lpDIBBits; // Pointer to DIB bits
BOOL bSuccess=FALSE; // Success/fail flag
HPALETTE hOldPal=NULL; // Previous palette
// Check for valid DIB handle
if (!hDIB)
return FALSE; // Lock down the DIB, and get a pointer to the beginning of the bit
// buffer
lpDIBHdr = (LPBYTE)GlobalLock(hDIB);
lpDIBBits = lpDIBHdr + sizeof(BITMAPINFOHEADER) +
colorNum*sizeof(RGBQUAD);
// if no palette provided, create one from DIB if (hPal)
{
hOldPal = SelectPalette(hDC, hPal, TRUE);
RealizePalette(hDC);
}
// Make sure to use the stretching mode best for color pictures
SetStretchBltMode(hDC, COLORONCOLOR);
// Call StretchDIBits() with dwRop
CRect pRect;
GetClientRect(pRect);
// ClientToScreen(pRect); bSuccess = ::SetDIBitsToDevice(hDC, 0, 0, ((LPBITMAPINFOHEADER)lpDIBHdr)->biWidth,((LPBITMAPINFOHEADER)lpDIBHdr)->biHeight, 0,0,0, ((LPBITMAPINFOHEADER)lpDIBHdr)->biHeight,lpDIBBits,(LPBITMAPINFO)lpDIBHdr,DIB_RGB_COLORS);
// Unlock the memory block
GlobalUnlock(hDIB);
// Reselect old palette
if (hOldPal)
SelectPalette(hDC, hOldPal, FALSE);
// Return with success/fail flag
return bSuccess;
}
DWORD dwBitsSize;
HANDLE hDIBtmp; // Used for GlobalRealloc() //MPB
LPBITMAPINFOHEADER lpbi;
DWORD offBits;
DWORD dwRead;
// get length of DIB in bytes for use when reading
dwBitsSize = pFile->GetLength();
// Allocate memory for header & color table. We'll enlarge this
// memory as needed.
m_hDIB = GlobalAlloc(GMEM_MOVEABLE, (DWORD)(sizeof(BITMAPINFOHEADER) +
256 * sizeof(RGBQUAD)));
if (!m_hDIB)
return FALSE;
lpbi = (LPBITMAPINFOHEADER)GlobalLock(m_hDIB);
if (!lpbi)
{
GlobalFree(m_hDIB);
return FALSE;
}
if (!ReadFile(pFile->m_hFile, (LPBYTE)lpbi, sizeof(BITMAPINFOHEADER), &dwRead,
NULL))
{
GlobalFree(m_hDIB);
return FALSE;
}
if (sizeof(BITMAPINFOHEADER) != dwRead)
{
GlobalFree(m_hDIB);
return FALSE;
}
if (lpbi->biSize == sizeof(BITMAPCOREHEADER))
{
GlobalFree(m_hDIB);
return FALSE; } lpbi->biBitCount = 8;
lpbi->biClrImportant = 256;
lpbi->biClrUsed = 256;
lpbi->biCompression = BI_RGB;
lpbi->biHeight = 600;
lpbi->biWidth = 600;
lpbi->biPlanes = 1;
lpbi->biSize = sizeof(BITMAPINFOHEADER);
lpbi->biSizeImage = 0;
lpbi->biXPelsPerMeter = 0;
lpbi->biYPelsPerMeter = 0; m_nColorNum = 256; // get a proper-sized buffer for header, color table and bits
GlobalUnlock(m_hDIB);
hDIBtmp = GlobalReAlloc(m_hDIB, lpbi->biSize + m_nColorNum *
sizeof(RGBQUAD) + lpbi->biSizeImage, 0);
if (!hDIBtmp) // can't resize buffer for loading
return FALSE;
else
m_hDIB = hDIBtmp;
lpbi = (LPBITMAPINFOHEADER)GlobalLock(m_hDIB);
offBits = lpbi->biSize + m_nColorNum * sizeof(RGBQUAD);
if (!ReadFile(pFile->m_hFile, (LPBYTE)lpbi + offBits, lpbi->biSizeImage, &dwRead,
NULL))
return FALSE;
GlobalUnlock(m_hDIB);
return TRUE;
/////////////////////////////////////////////////////////////////make palette
HPALETTE CBitmapShowDoc::CreateDIBPalette(LPBYTE lpbi)
{
LPLOGPALETTE lpPal; // pointer to a logical palette
HANDLE hLogPal; // handle to a logical palette
HPALETTE hPal = NULL;// handle to a palette
int i, wNumColors; // loop index, number of colors in color table
LPBITMAPINFO lpbmi; // pointer to BITMAPINFO structure (Win3.0)
LPBITMAPCOREINFO lpbmc; // pointer to BITMAPCOREINFO structure (OS/2)
// if handle to DIB is invalid, return NULL
if (! lpbi)
return NULL;
// get pointer to BITMAPINFO (Win 3.0)
lpbmi = (LPBITMAPINFO)lpbi;
// get pointer to BITMAPCOREINFO (OS/2 1.x)
wNumColors = m_nColorNum;
// is this a Win 3.0 DIB?
if (wNumColors)
{
// allocate memory block for logical palette
hLogPal = GlobalAlloc(GHND, sizeof(LOGPALETTE) +
sizeof(PALETTEENTRY) * wNumColors);
// if not enough memory, clean up and return NULL
if (!hLogPal)
return NULL;
// lock memory block and get pointer to it
lpPal = (LPLOGPALETTE)GlobalLock(hLogPal);
// set version and number of palette entries
lpPal->palVersion = 0x300;
lpPal->palNumEntries = wNumColors;
// store RGB triples (if Win 3.0 DIB) or RGB quads (if OS/2 DIB)
// into palette
for (i = 0; i < wNumColors; i++)
{
int j;
j = i*3;
lpPal->palPalEntry[i].peRed = j;//lpbmi->bmiColors[i].rgbRed;
lpPal->palPalEntry[i].peGreen = j;//lpbmi->bmiColors[i].rgbGreen;
lpPal->palPalEntry[i].peBlue = j;//lpbmi->bmiColors[i].rgbBlue;
lpPal->palPalEntry[i].peFlags = 0;
}
// create the palette and get handle to it
hPal = CreatePalette(lpPal);
// if error getting handle to palette, clean up and return NULL
if (!hPal)
{
GlobalUnlock(hLogPal);
GlobalFree(hLogPal);
return NULL;
}
}
// return handle to DIB's palette
return hPal;
///////////////////////////////////////////////////////////show image
BOOL CBitmapShowView::PaintDIB(HDC hDC, HANDLE hDIB, HPALETTE hPal, int colorNum)
{
LPBYTE lpDIBHdr; // Pointer to BITMAPINFOHEADER
LPBYTE lpDIBBits; // Pointer to DIB bits
BOOL bSuccess=FALSE; // Success/fail flag
HPALETTE hOldPal=NULL; // Previous palette
// Check for valid DIB handle
if (!hDIB)
return FALSE; // Lock down the DIB, and get a pointer to the beginning of the bit
// buffer
lpDIBHdr = (LPBYTE)GlobalLock(hDIB);
lpDIBBits = lpDIBHdr + sizeof(BITMAPINFOHEADER) +
colorNum*sizeof(RGBQUAD);
// if no palette provided, create one from DIB if (hPal)
{
hOldPal = SelectPalette(hDC, hPal, TRUE);
RealizePalette(hDC);
}
// Make sure to use the stretching mode best for color pictures
SetStretchBltMode(hDC, COLORONCOLOR);
// Call StretchDIBits() with dwRop
CRect pRect;
GetClientRect(pRect);
// ClientToScreen(pRect); bSuccess = ::SetDIBitsToDevice(hDC, 0, 0, ((LPBITMAPINFOHEADER)lpDIBHdr)->biWidth,((LPBITMAPINFOHEADER)lpDIBHdr)->biHeight, 0,0,0, ((LPBITMAPINFOHEADER)lpDIBHdr)->biHeight,lpDIBBits,(LPBITMAPINFO)lpDIBHdr,DIB_RGB_COLORS);
// Unlock the memory block
GlobalUnlock(hDIB);
// Reselect old palette
if (hOldPal)
SelectPalette(hDC, hOldPal, FALSE);
// Return with success/fail flag
return bSuccess;
}
void CTestDlg::OnButton1()
{
// TODO: Add your control notification handler code here CFile file;
file.Open("t.bmp", CFile::modeRead, NULL) //1.读入bmpfileheader
BITMAPFILEHEADER bitmapfileheader;
file.Read((LPSTR)&bitmapfileheader, sizeof(bitmapfileheader);
//2.读入bmpinfoheader
int nInfoSize=bitmapfileheader.bfOffBits-sizeof(bitmapfileheader);
BITMAPINFO * lpBitmapinfo=(BITMAPINFO *)new char[nInfoSize];
file.Read((LPSTR)lpBitmapinfo,nInfoSize);
//3.读入图像内容
long nImageSize=bitmapfileheader.bfSize-bitmapfileheader.bfOffBits;
unsigned char * lpDIBBits=new unsigned char[nImageSize];
file.ReadHuge(lpDIBBits,nImageSize);
//4.显示处理
CClientDC dc(this);
SetDIBitsToDevice(dc.m_hDC, 100, 0,
lpBitmapinfo->bmiHeader.biWidth,lpBitmapinfo->bmiHeader.biHeight, 0,0,0,
lpBitmapinfo->bmiHeader.biHeight,
lpDIBBits,lpBitmapinfo,DIB_RGB_COLORS);
//退出
delete lpBitmapinfo;
delete []lpDIBBits;
file.Close();
}
---------------------
typedef struct tagBITMAPINFO {
BITMAPINFOHEADER bmiHeader;
RGBQUAD bmiColors[1];
} BITMAPINFO, FAR *LPBITMAPINFO, *PBITMAPINFO;操作2时候将 bmiColors读入, 在SetDIBitsToDevice显示时候就会采用. 你的代码没有读入bmiColors内容.