当前这个帖子可以参考实现把3D位图模式应用于文本或其他图形。
假设我们一些文本和图形,而这些文本和图形需要上色,并且不是单一的某种颜色,而是把某异种位图的颜色模式应用于它,
我们可以采用本程序的办法来实现。
其实现的效果参见下图:
左图是需要上色的文本和图形,
中间是需要的颜色模式,
右边是上色的结果。
MFC将位置应用于文本上
EmbossPattern()思路与上一帖子提取的Emboss()函数相似。
//prototype for default arguments - add this to your header file
HBITMAP EmbossPattern( HBITMAP hBitmap, HBITMAP hbmPattern, HPALETTE hPal,
BOOL bRaised = TRUE,
COLORREF clrHighlight = GetSysColor( COLOR_BTNHIGHLIGHT ),
COLORREF clrShadow = GetSysColor( COLOR_BTNSHADOW ) );
/////////////////////////////////////////////////////////////////////////////////////
// EmbossPattern - Creates a 3D effect and draws the pattern on the foreground
// but leaves the background alone
// Returns - A new bitmap containing the resulting effect
// hBitmap - Bitmap that contains the basic text & shapes
// hbmBackGnd - Contains the color image
// hPal - Handle of palette associated with hbmBackGnd
// bRaised - True if raised effect is desired. False for sunken effect
// xDest - x coordinate - used to offset hBitmap
// yDest - y coordinate - used to offset hBitmap
// clrHightlight - Color used for the highlight edge
// clrShadow - Color used for the shadow
//
// Note - 1. Neither of the bitmap handles passed in should be selected
// in a device context.
// 2. The pixel at 0,0 in hBitmap is considered the background color
//
HBITMAP EmbossPattern( HBITMAP hBitmap, HBITMAP hbmPattern, HPALETTE hPal,
BOOL bRaised, COLORREF clrHighlight, COLORREF clrShadow)
{
const DWORD PSDPxax = 0x00B8074A;
BITMAP bmInfo ;
HBITMAP hbmOld, hbmShadow, hbmHighlight, hbmResult, hbmOldMem, hbmMono ;
HBRUSH hbrPat ;
HDC hDC, hColorDC, hMonoDC, hMemDC ;
if( !bRaised )
{
// Swap the highlight and shadow color
COLORREF clrTemp = clrShadow;
clrShadow = clrHighlight;
clrHighlight = clrTemp;
}
// We create three monochrome bitmaps. One of them will contain the
// monochrome version of the bitmap primary bitmap. One will contain
// highlighted edge and the third will contain the shadow. These
// bitmaps are then used to paint the highlight and shadow on the
// background image.
hbmResult = NULL ;
hDC = GetDC( NULL ) ;
// Create a compatible DCs
hMemDC = ::CreateCompatibleDC( hDC );
hMonoDC = CreateCompatibleDC( hDC );
hColorDC = CreateCompatibleDC( hDC );
if( hMemDC == NULL || hMonoDC == NULL || hColorDC == NULL )
{
if( hMemDC ) DeleteDC( hMemDC );
if( hMonoDC ) DeleteDC( hMonoDC );
if( hColorDC ) DeleteDC( hColorDC );
return NULL;
}
// Select the Pattern image into memory DC so that we can draw it
hbmOldMem = (HBITMAP)::SelectObject( hMemDC, hbmPattern );
// Get dimensions of the pattern image
BITMAP bm;
::GetObject( hbmPattern, sizeof( bm ), &bm );
// Create the monochrome and compatible color bitmaps
GetObject( hBitmap, sizeof( BITMAP ), (LPSTR) &bmInfo ) ;
hbmMono =
CreateBitmap( bmInfo.bmWidth, bmInfo.bmHeight, 1, 1, NULL ) ;
hbmShadow =
CreateBitmap( bmInfo.bmWidth, bmInfo.bmHeight, 1, 1, NULL ) ;
hbmHighlight =
CreateBitmap( bmInfo.bmWidth, bmInfo.bmHeight, 1, 1, NULL ) ;
hbmResult =
CreateCompatibleBitmap( hDC, bmInfo.bmWidth, bmInfo.bmHeight ) ;
hbmOld = (HBITMAP)SelectObject( hColorDC, hBitmap ) ;
// Set background color of bitmap for mono conversion
// We assume that the pixel in the top left corner has the background color
COLORREF clrBackGnd = GetPixel( hColorDC, 10, 10 );
SetBkColor( hColorDC, clrBackGnd ) ;
// Create the monochrome version of the bitmap.
hbmMono = (HBITMAP)SelectObject( hMonoDC, (HGDIOBJ) hbmMono ) ;
BitBlt( hMonoDC, 0, 0, bmInfo.bmWidth, bmInfo.bmHeight,
hColorDC, 0, 0, SRCCOPY ) ;
hbmMono = (HBITMAP)SelectObject( hMonoDC, (HGDIOBJ) hbmMono ) ;
// Create the highlight bitmap.
hbmHighlight = (HBITMAP)SelectObject( hMonoDC, (HGDIOBJ) hbmHighlight ) ;
PatBlt( hMonoDC, 0, 0, bmInfo.bmWidth, bmInfo.bmHeight, WHITENESS ) ;
BitBlt( hMonoDC, 0, 0, bmInfo.bmWidth - 1, bmInfo.bmHeight - 1,
hColorDC, 1, 1, SRCCOPY ) ;
BitBlt( hMonoDC, 0, 0, bmInfo.bmWidth, bmInfo.bmHeight,
hColorDC, 0, 0, MERGEPAINT ) ;
hbmHighlight = (HBITMAP)SelectObject( hMonoDC, (HGDIOBJ) hbmHighlight ) ;
// create the shadow bitmap
hbmShadow = (HBITMAP)SelectObject( hMonoDC, (HGDIOBJ) hbmShadow ) ;
PatBlt( hMonoDC, 0, 0, bmInfo.bmWidth, bmInfo.bmHeight, WHITENESS ) ;
BitBlt( hMonoDC, 1, 1, bmInfo.bmWidth-1, bmInfo.bmHeight-1,
hColorDC, 0, 0, SRCCOPY ) ;
BitBlt( hMonoDC, 0, 0, bmInfo.bmWidth, bmInfo.bmHeight,
hColorDC, 0, 0, MERGEPAINT ) ;
hbmShadow = (HBITMAP)SelectObject( hMonoDC, (HGDIOBJ) hbmShadow ) ;
// Now let's start working on the final image
SelectObject( hColorDC, hbmResult ) ;
// Select and realize the palette if one is supplied
if( hPal && GetDeviceCaps(hDC, RASTERCAPS) & RC_PALETTE )
{
::SelectPalette( hColorDC, hPal, FALSE );
::RealizePalette(hColorDC);
}
// Draw the pattern image - tile it if needed
for( int w = 0; w < bmInfo.bmWidth; w += bm.bmWidth )
{
for( int h = 0; h < bmInfo.bmHeight; h += bm.bmHeight )
BitBlt(hColorDC, w, h, bm.bmWidth, bm.bmWidth, hMemDC,
0, 0,SRCCOPY);
}
// Restore the old bitmap in the hMemDC
::SelectObject( hMemDC, hbmOldMem );
// Set the background and foreground color for the raster operations
SetBkColor( hColorDC, RGB(0,0,0) ) ;
SetTextColor( hColorDC, RGB(255,255,255) ) ;
hbrPat = CreateSolidBrush( clrBackGnd ) ;
hbrPat = (HBRUSH)SelectObject( hColorDC, hbrPat ) ;
hbmMono = (HBITMAP)SelectObject( hMonoDC, (HGDIOBJ) hbmMono );
BitBlt( hColorDC, 0, 0, bmInfo.bmWidth, bmInfo.bmHeight,
hMonoDC, 0, 0, PSDPxax ) ;
DeleteObject( SelectObject( hColorDC, hbrPat ) ) ;
hbmMono = (HBITMAP)SelectObject( hMonoDC, (HGDIOBJ) hbmMono ) ;
// Set the background and foreground color for the raster operations
SetBkColor( hColorDC, RGB(255,255,255) ) ;
SetTextColor( hColorDC, RGB(0,0,0) ) ;
// blt the highlight edge
hbrPat = CreateSolidBrush( clrHighlight ) ;
hbrPat = (HBRUSH)SelectObject( hColorDC, hbrPat ) ;
hbmHighlight = (HBITMAP)SelectObject( hMonoDC, (HGDIOBJ) hbmHighlight ) ;
BitBlt( hColorDC, 0, 0, bmInfo.bmWidth, bmInfo.bmHeight,
hMonoDC, 0, 0, PSDPxax ) ;
DeleteObject( SelectObject( hColorDC, hbrPat ) ) ;
hbmHighlight = (HBITMAP)SelectObject( hMonoDC, (HGDIOBJ) hbmHighlight ) ;
// blt the shadow edge
hbrPat = CreateSolidBrush( clrShadow ) ;
hbrPat = (HBRUSH)SelectObject( hColorDC, hbrPat ) ;
hbmShadow = (HBITMAP)SelectObject( hMonoDC, (HGDIOBJ) hbmShadow ) ;
BitBlt( hColorDC, 0, 0, bmInfo.bmWidth, bmInfo.bmHeight,
hMonoDC, 0, 0, PSDPxax ) ;
DeleteObject( SelectObject( hColorDC, hbrPat ) ) ;
hbmShadow = (HBITMAP)SelectObject( hMonoDC, (HGDIOBJ) hbmShadow ) ;
// select old bitmap into color DC
SelectObject( hColorDC, hbmOld ) ;
DeleteObject( (HGDIOBJ) hbmMono ) ;
DeleteObject( (HGDIOBJ) hbmShadow ) ;
DeleteObject( (HGDIOBJ) hbmHighlight ) ;
ReleaseDC( NULL, hDC ) ;
return ( hbmResult ) ;
}
|