假设你有一些文本和图形,而这些文本和图形需要上色,并且不是单一的某种颜色,而是把某异种位图的颜色模式应用于它,你可以采用本程序的办法来实现。其实现的效果参见下图:左图是需要上色的文本和图形,中间是需要的颜色模式,右边是上色的结果。
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 ) ; }