www.pudn.com > mfc资源大全1.rar > 256color_bitmap.shtml
Bitmap & Palette - Displaying a 256 color bitmap
Anyway cutting to the chase, to display a 256 color bitmap, you have to create a logical palette from the color table in the bitmap, select the palette into the device context, realize the palette and BitBlt the bitmap to the device context.
The first thing the function does is that it loads the bitmap and attaches it to a CBitmap object. We use a call to the global ::LoadImage() rather than to the CBitmap::LoadBitmap(). The reason for this is that we want to be able to access the DIBSECTION of the bitmap and the reason why we want the DIBSECTION is because we want to access the color information in the bitmap to create a logical palette that matches the colors used by the bitmap. Calling LoadBitmap() would result in the loss of the color information.
Once we have the bitmap, we start working on creating the logical palette. We determine the number of colors used by the bitmap by getting access to the DIBSECTION by calling the Cbitmap::GetObject() function. Note that the documentation for this function does not mention the DIBSECTION, you'd have to look up the documention of the ::GetObject() function in the API section instead. Sometimes the BITMAPINFOHEADER which is part of the DIBSECTION does not specify how many colors it uses. If this is the case we infer the color count from the number of bits it uses for the each pixel. For example, 8 bits can represent 256 different values and therefore indicates 256 colors. Similarly, 16 bits indicates 64K colors.
A bitmap that uses more than 256 colors does not have a color table. In this situation we simply create a halftone palette compatible with the device context. A halftone palette is basically a palette that contains a sampling of all the different colors. This is certainly not the best solution but it is the simplest.
If the bitmap has 256 colors or less, we do create the palette. We allocate enough space to hold the color table of the bitmap and call the function ::GetDIBColorTable() to retrieve it from the bitmap. We also allocate enough memory to create a logical palette and copy the color entries from the bitmap's color table. The palVersion field should be 0x300.
After creating the CPalette object, we deallocate the memory blocks allocated earlier and invalidate the window so that it can be redrawn using the new image.
BOOL GetBitmapAndPalette(UINT nIDResource, CBitmap &bitmap, CPalette &pal)
{
LPCTSTR lpszResourceName = (LPCTSTR)nIDResource;
HBITMAP hBmp = (HBITMAP)::LoadImage( AfxGetInstanceHandle(),
lpszResourceName, IMAGE_BITMAP, 0,0, LR_CREATEDIBSECTION );
if( hBmp == NULL )
return FALSE;
bitmap.Attach( hBmp );
// Create a logical palette for the bitmap
DIBSECTION ds;
BITMAPINFOHEADER &bmInfo = ds.dsBmih;
bitmap.GetObject( sizeof(ds), &ds );
int nColors = bmInfo.biClrUsed ? bmInfo.biClrUsed : 1 << bmInfo.biBitCount;
// Create a halftone palette if colors > 256.
CClientDC dc(NULL); // Desktop DC
if( nColors > 256 )
pal.CreateHalftonePalette( &dc );
else
{
// Create the palette
RGBQUAD *pRGB = new RGBQUAD[nColors];
CDC memDC;
memDC.CreateCompatibleDC(&dc);
memDC.SelectObject( &bitmap );
::GetDIBColorTable( memDC, 0, nColors, pRGB );
UINT nSize = sizeof(LOGPALETTE) + (sizeof(PALETTEENTRY) * nColors);
LOGPALETTE *pLP = (LOGPALETTE *) new BYTE[nSize];
pLP->palVersion = 0x300;
pLP->palNumEntries = nColors;
for( int i=0; i < nColors; i++)
{
pLP->palPalEntry[i].peRed = pRGB[i].rgbRed;
pLP->palPalEntry[i].peGreen = pRGB[i].rgbGreen;
pLP->palPalEntry[i].peBlue = pRGB[i].rgbBlue;
pLP->palPalEntry[i].peFlags = 0;
}
pal.CreatePalette( pLP );
delete[] pLP;
delete[] pRGB;
}
return TRUE;
}
void CMyWindow::OnPaint()
{
CPaintDC dc(this);
// Create a memory DC compatible with the paint DC
CDC memDC;
memDC.CreateCompatibleDC( &dc );
CBitmap bitmap;
CPalette palette;
GetBitmapAndPalette( IDB_BITMAP, bitmap, palette );
memDC.SelectObject( &bitmap );
// Select and realize the palette
if( dc.GetDeviceCaps(RASTERCAPS) & RC_PALETTE && palette.m_hObject != NULL )
{
dc.SelectPalette( &palette, FALSE );
dc.RealizePalette();
}
dc.BitBlt(0, 0, 180, 180, &memDC, 0, 0,SRCCOPY);
}
| Goto HomePage |
|
Contact me: zafir@home.com
|