www.pudn.com > mfc资源大全1.rar > draw_bitmap.shtml
Bitmap & Palette - Drawing a bitmap
The device-dependent bitmap is specific to a device and it is very unlikely that a DDB for one device can be rendered on another. One such situation is when you want to render an image from the screen to a printer. In this case you would have to change the DDB to a DIB before you try to render it onto the printer. Most of the GDI functions take a DDB as an argument instead on a DIB.
The DIB section is somewhat new and designed to alleviate some of the problems with a DIB. You can use a DIB section wherever you use a DDB and yet have access to the bitmap bits and the color information. All this preamble was basically to say that you need one function to render a DIB and another to render a DDB or a DIB section.
You can also use the StretchDIBits() to render the bitmap data onto a device. The StretchDIBits() function is more versatile in that it allows the bitmap to be streched or compressed and it can use various raster operations to generate the image. The StretchDIBits() function can also be used to mirror the image.
One of the argument to the DrawDIB() function is the palette that should be used when rendering the bitmap. This information can be derived from the DIB itself but using a predefined palette can help speed things up slightly.
// DrawDIB - Draws a DIB onto a device
// pDC - Pointer to a device context
// hDIB - Handle of the device-independent bitmap
// pPal - Pointer to a palette associated with the DIB
// xDest - x-coordinate of the upper-left corner of the destination rect
// yDest - y-coordinate of the upper-left corner of the destination rect
void DrawDIB( CDC* pDC, HGLOBAL hDIB, CPalette *pPal, int xDest, int yDest )
{
LPVOID lpDIBBits; // Pointer to DIB bits
BOOL bSuccess=FALSE; // Success/fail flag
BITMAPINFO &bmInfo = *(LPBITMAPINFO)hDIB ;
int nColors = bmInfo.bmiHeader.biClrUsed ? bmInfo.bmiHeader.biClrUsed :
1 << bmInfo.bmiHeader.biBitCount;
// Compute the address of the bitmap bits
if( bmInfo.bmiHeader.biBitCount > 8 )
lpDIBBits = (LPVOID)((LPDWORD)(bmInfo.bmiColors +
bmInfo.bmiHeader.biClrUsed) +
((bmInfo.bmiHeader.biCompression == BI_BITFIELDS) ? 3 : 0));
else
lpDIBBits = (LPVOID)(bmInfo.bmiColors + nColors);
// Select and realize the palette if one supplied and if device supports it
if( pPal && (pDC->GetDeviceCaps(RASTERCAPS) & RC_PALETTE) )
{
pDC->SelectPalette(pPal, FALSE);
pDC->RealizePalette();
}
::SetDIBitsToDevice(pDC->m_hDC, // hDC
xDest, // DestX
yDest, // DestY
bmInfo.bmiHeader.biWidth, // nDestWidth
bmInfo.bmiHeader.biHeight, // nDestHeight
0, // SrcX
0, // SrcY
0, // nStartScan
bmInfo.bmiHeader.biHeight, // nNumScans
lpDIBBits, // lpBits
(LPBITMAPINFO)hDIB, // lpBitsInfo
DIB_RGB_COLORS); // wUsage
}
// DrawBitmap - Draws a bitmap (DDB & DIB section) onto a device
// pDC - Pointer to a device context
// hBitmap - Handle of the bitmap
// hPal - Handle of a logical palette associated with the bitmap
// xDest - x-coordinate of the upper-left corner of the destination rect
// yDest - y-coordinate of the upper-left corner of the destination rect
void DrawBitmap( CDC *pDC, HBITMAP hBitmap, HPALETTE hPal, int xDest, int yDest )
{
// Get logical coordinates
BITMAP bm;
::GetObject( hBitmap, sizeof( bm ), &bm );
CPoint size( bm.bmWidth, bm.bmHeight );
pDC->DPtoLP(&size);
CPoint org(0,0);
pDC->DPtoLP(&org);
// Create a memory DC compatible with the destination DC
CDC memDC;
memDC.CreateCompatibleDC( pDC );
memDC.SetMapMode( pDC->GetMapMode() );
//memDC.SelectObject( &bitmap );
HBITMAP hBmOld = (HBITMAP)::SelectObject( memDC.m_hDC, hBitmap );
// Select and realize the palette
if( hPal && pDC->GetDeviceCaps(RASTERCAPS) & RC_PALETTE)
{
SelectPalette( pDC->GetSafeHdc(), hPal, FALSE );
pDC->RealizePalette();
}
pDC->BitBlt(xDest, yDest, size.x, size.y, &memDC, org.x, org.y, SRCCOPY);
::SelectObject( memDC.m_hDC, hBmOld );
}
// DrawDIBSection - Draws a DIB section onto a device
// hDC - Handle to a device context
// hBitmap - Handle of the DIB Section
// xDest - x-coordinate of the upper-left corner of the destination rect
// yDest - y-coordinate of the upper-left corner of the destination rect
void DrawDIBSection( HDC hDC, HBITMAP hBitmap, int xDest, int yDest )
{
HPALETTE hPal;
HDC hDCMem = ::CreateCompatibleDC( hDC );
// Create a logical palette for the bitmap
DIBSECTION ds;
BITMAPINFOHEADER &bmInfo = ds.dsBmih;
if( ::GetObject(hBitmap, sizeof(ds), &ds ) == 0 )
return; // Not a DIB Section
HGDIOBJ hBmpOld = ::SelectObject(hDCMem, hBitmap);
int nColors = bmInfo.biClrUsed ? bmInfo.biClrUsed : 1 << ds.dsBm.bmBitsPixel;
if( ::GetDeviceCaps(hDC, RASTERCAPS) & RC_PALETTE )
{
// Create a halftone palette if colors > 256.
if( nColors > 256 )
hPal = ::CreateHalftonePalette(hDC);
else
{
// Create the palette
RGBQUAD *pRGB = new RGBQUAD[nColors];
::GetDIBColorTable( hDCMem, 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;
}
hPal = ::CreatePalette( pLP );
delete[] pLP;
delete[] pRGB;
}
HPALETTE hPalOld = ::SelectPalette(hDC,hPal,FALSE);
::RealizePalette(hDC);
BitBlt(hDC,xDest,yDest,bmInfo.biWidth,bmInfo.biHeight,hDCMem,0,0,SRCCOPY);
::SelectPalette(hDC,hPalOld,FALSE);
// delete GDI objects
::DeleteObject(hPal);
}
else
BitBlt(hDC,xDest,yDest,bmInfo.biWidth,bmInfo.biHeight,hDCMem,0,0,SRCCOPY);
::SelectObject(hDCMem, hBmpOld);
::DeleteDC(hDCMem);
}
| Goto HomePage |
|
Contact me: zafir@home.com
|