透明色

透明色(转)
你可以先将Bitmap位图变为透明的,然后再保存当前的Bitmap位图.

包含透明色的位图的绘制方法有多种,最简单的方法是调用现成的函数:TransparentBlt,也可以通过自己的代码实现类似 TransparentBlt的功能,实现过程也有两种形式,一种是事先做一张掩码位图,另一种是动态生成掩码位图。本文将介绍动态生成掩码位图绘制具有透明区域位图的方法。

一、TransparentBlt   函数的使用  

TransparentBlt   函数在Windows98
/ Windows2000以上版本运行,系统中需要包含   Msimg32.dll,使用时可以链接   Msimg32.lib。
Windows98下的TransparentBlt会产生资源泄漏,所以不建议在WIN98下使用该函数。
TransparentBlt函数原型如下:  

BOOL   TransparentBlt(

HDC   hdcDest,             
//    目标DC

int    nXOriginDest,        //    目标X偏移

int    nYOriginDest,        //    目标Y偏移

int    nWidthDest,            //    目标宽度

int    hHeightDest,          //    目标高度

HDC   hdcSrc,                   
//    源DC

int    nXOriginSrc,          //    源X起点

int    nYOriginSrc,          //    源Y起点

int    nWidthSrc,              //    源宽度

int    nHeightSrc,            //    源高度

UINT   crTransparent     
//    透明色,COLORREF类型

);

使用示例:  

CBitmap   FootballBMP;

FootballBMP.LoadBitmap(IDB_FOOTBALLBMP);

CDC   ImageDC;

ImageDC.CreateCompatibleDC(pDC);

CBitmap   
* pOldImageBMP    =    ImageDC.SelectObject( & FootballBMP);

TransparentBlt(pDC
->  m_hDC,    0 ,    0 ,    218 ,    199 ,   ImageDC.m_hDC,    0 ,    0 ,    218 ,    199 ,   RGB( 0 , 0 , 0xff ));

ImageDC.SelectObject(pOldImageBMP);

二、实现TransparentBlt函数

为了理解具有透明色位图的绘制过程,我们来亲手建立一个具有同TransparentBlt功能一致的实验函数,称之为TransparentBlt2。

实验素材:有两张位图:bk.bmp是背景位图,football.bmp包含透明区域,透明色为蓝色RGB(
0 , 0 , 0xff )
实验目的:以bk.bmp为背景,将football.bmp绘制到背景中。


2.1    透明位图绘制原理
假设football.bmp   
->  载入   HBITMAP   hImageBMP    ->    选入   HDC   hImageDC

2.1 . 1    生成单色掩码位图,透明区域为白色(全1),非透明区域为黑色(全0)  

HBITMAP   hMaskBMP   
=    CreateBitmap(nWidthDest,   nHeightDest,    1 ,    1 ,   NULL);    //    建立单色位图

SetBkColor(hImageDC,   RGB(
0 , 0 , 0xff ));    //    设置背景色为蓝色

BitBlt(hMaskDC,   
0 ,    0 ,   nWidthDest,   nHeightDest,   hImageDC,    0 ,    0 ,   SRCCOPY);    //    拷贝到hMaskDC

这样足球位图中蓝色区域在掩码位图中成了白色,其它区域为黑色。


2.1 . 2    设置背景色为黑色,前景色为白色,将掩码位图与足球位图相  " 与  "   

SetBkColor(hImageDC,   RGB(
0 , 0 , 0 ));

SetTextColor(hImageDC,   RGB(
255 , 255 , 255 ));

BitBlt(hImageDC,   
0 ,    0 ,   nWidthDest,   nHeightDest,   hMaskDC,    0 ,    0 ,   SRCAND);

这样,掩码位图中背景色(黑色)的区域在hImageBMP中被保留,前景色(白色)的部分变为黑色。  

2.1 . 3    设置背景色为白色,前景色为黑色,将掩码位图与背景进行“与”运算

SetBkColor(hdcDest,RGB(
255 , 255 , 255 ));

SetTextColor(hdcDest,RGB(
0 , 0 , 0 ));

BitBlt(hdcDest,   nXOriginDest,   nYOriginDest,   nWidthDest,   nHeightDest,   hMaskDC,   
0 ,    0 ,   SRCAND);

掩码中白色区域(数据与1相“与”结果不变)使背景保持不变,黑色区域变成黑色。
2.1 . 4    将hImageBMP与背景进行“或”运算  

BitBlt(hdcDest,   nXOriginDest,   nYOriginDest,   nWidthDest,   nHeightDest,   hImageDC,   
0 ,    0 ,   SRCPAINT);

这样就将位图绘制到背景上了。

2.2    TransparentBlt2函数全部实现代码

void    TransparentBlt2(   HDC   hdcDest,              //    目标DC

                                                                            
int    nXOriginDest,        //    目标X偏移

                                                                            
int    nYOriginDest,        //    目标Y偏移

                                                                            
int    nWidthDest,            //    目标宽度

                                                                            
int    nHeightDest,          //    目标高度

                                                                            HDC   hdcSrc,                   
//    源DC

                                                                            
int    nXOriginSrc,          //    源X起点

                                                                            
int    nYOriginSrc,          //    源Y起点

                                                                            
int    nWidthSrc,              //    源宽度

                                                                            
int    nHeightSrc,            //    源高度

                                                                            UINT   crTransparent     
//    透明色,COLORREF类型

                                                                            )

{

                HBITMAP   hOldImageBMP,   hImageBMP   
=    CreateCompatibleBitmap(hdcDest,   nWidthDest,   nHeightDest);      //    创建兼容位图

                HBITMAP   hOldMaskBMP,   hMaskBMP   
=    CreateBitmap(nWidthDest,   nHeightDest,    1 ,    1 ,   NULL);                          //    创建单色掩码位图

                HDC                         hImageDC   
=    CreateCompatibleDC(hdcDest);

                HDC                         hMaskDC   
=    CreateCompatibleDC(hdcDest);

                hOldImageBMP   
=    (HBITMAP)SelectObject(hImageDC,   hImageBMP);

                hOldMaskBMP   
=    (HBITMAP)SelectObject(hMaskDC,   hMaskBMP);

 

                
//    将源DC中的位图拷贝到临时DC中

                
if    (nWidthDest    ==    nWidthSrc    &&    nHeightDest    ==    nHeightSrc)

                              BitBlt(hImageDC,   
0 ,    0 ,   nWidthDest,   nHeightDest,   hdcSrc,   nXOriginSrc,   nYOriginSrc,   SRCCOPY);

                
else

                              StretchBlt(hImageDC,   
0 ,    0 ,   nWidthDest,   nHeightDest,  

                                                                            hdcSrc,   nXOriginSrc,   nYOriginSrc,   nWidthSrc,   nHeightSrc,   SRCCOPY);

 

                
//    设置透明色

                SetBkColor(hImageDC,   crTransparent);

 

                
//    生成透明区域为白色,其它区域为黑色的掩码位图

                BitBlt(hMaskDC,   
0 ,    0 ,   nWidthDest,   nHeightDest,   hImageDC,    0 ,    0 ,   SRCCOPY);

 

                
//    生成透明区域为黑色,其它区域保持不变的位图

                SetBkColor(hImageDC,   RGB(
0 , 0 , 0 ));

                SetTextColor(hImageDC,   RGB(
255 , 255 , 255 ));

                BitBlt(hImageDC,   
0 ,    0 ,   nWidthDest,   nHeightDest,   hMaskDC,    0 ,    0 ,   SRCAND);

 

                
//    透明部分保持屏幕不变,其它部分变成黑色

                SetBkColor(hdcDest,RGB(
255 , 255 , 255 ));

                SetTextColor(hdcDest,RGB(
0 , 0 , 0 ));

                BitBlt(hdcDest,   nXOriginDest,   nYOriginDest,   nWidthDest,   nHeightDest,   hMaskDC,   
0 ,    0 ,   SRCAND);

 

                
//    "或 "运算,生成最终效果

                BitBlt(hdcDest,   nXOriginDest,   nYOriginDest,   nWidthDest,   nHeightDest,   hImageDC,   
0 ,    0 ,   SRCPAINT);

 

                
//    清理、恢复    

                SelectObject(hImageDC,   hOldImageBMP);

                DeleteDC(hImageDC);

                SelectObject(hMaskDC,   hOldMaskBMP);

                DeleteDC(hMaskDC);

                DeleteObject(hImageBMP);

                DeleteObject(hMaskBMP);

}
2.3    TransparentBlt的另外一个版本:TransparentBltU

TransparentBltU是Christian   Graus   在WinDEV发表的一个函数,功能与TransparentBlt一致,以下是全部实现代码:  

bool   TransparentBltU(

          HDC   dcDest,                   
//    handle   to   Dest   DC

          
int    nXOriginDest,        //    x-coord   of   destination   upper-left   corner

          
int    nYOriginDest,        //    y-coord   of   destination   upper-left   corner

          
int    nWidthDest,            //    width   of   destination   rectangle

          
int    nHeightDest,          //    height   of   destination   rectangle

          HDC   dcSrc,                     
//    handle   to   source   DC

          
int    nXOriginSrc,          //    x-coord   of   source   upper-left   corner

          
int    nYOriginSrc,          //    y-coord   of   source   upper-left   corner

          
int    nWidthSrc,              //    width   of   source   rectangle

          
int    nHeightSrc,            //    height   of   source   rectangle

          UINT   crTransparent     
//    color   to   make   transparent

    )

{

          
if    (nWidthDest    <     1 )    return     false ;

          
if    (nWidthSrc    <     1 )    return     false ;

          
if    (nHeightDest    <     1 )    return     false ;

          
if    (nHeightSrc    <     1 )    return     false ;

 

          HDC   dc   
=    CreateCompatibleDC(NULL);

          HBITMAP   bitmap   
=    CreateBitmap(nWidthSrc,   nHeightSrc,    1 ,   GetDeviceCaps(dc,

                                                                                                                            BITSPIXEL),   NULL);

 

          
if    (bitmap    ==    NULL)

          {

                  DeleteDC(dc);        

                  
return     false ;

          }

 

          HBITMAP   oldBitmap   
=    (HBITMAP)SelectObject(dc,   bitmap);

 

          
if    ( ! BitBlt(dc,    0 ,    0 ,   nWidthSrc,   nHeightSrc,   dcSrc,   nXOriginSrc,

                                                                                                                  nYOriginSrc,   SRCCOPY))

          {

                  SelectObject(dc,   oldBitmap);  

                  DeleteObject(bitmap);                

                  DeleteDC(dc);                                

                  
return     false ;

          }

 

          HDC   maskDC   
=    CreateCompatibleDC(NULL);

          HBITMAP   maskBitmap   
=    CreateBitmap(nWidthSrc,   nHeightSrc,    1 ,    1 ,   NULL);

 

          
if    (maskBitmap    ==    NULL)

          {

                  SelectObject(dc,   oldBitmap);  

                  DeleteObject(bitmap);                

                  DeleteDC(dc);                                

                  DeleteDC(maskDC);                        

                  
return     false ;

          }

 

          HBITMAP   oldMask   
=      (HBITMAP)SelectObject(maskDC,   maskBitmap);

 

          SetBkColor(maskDC,   RGB(
0 , 0 , 0 ));

          SetTextColor(maskDC,   RGB(
255 , 255 , 255 ));

          
if    ( ! BitBlt(maskDC,    0 , 0 ,nWidthSrc,nHeightSrc,NULL, 0 , 0 ,BLACKNESS))

          {

                  SelectObject(maskDC,   oldMask);  

                  DeleteObject(maskBitmap);            

                  DeleteDC(maskDC);                            

                  SelectObject(dc,   oldBitmap);      

                  DeleteObject(bitmap);                    

                  DeleteDC(dc);                                    

                  
return     false ;

          }

 

          SetBkColor(dc,   crTransparent);

          BitBlt(maskDC,   
0 , 0 ,nWidthSrc,nHeightSrc,dc, 0 , 0 ,SRCINVERT);

 

          SetBkColor(dc,   RGB(
0 , 0 , 0 ));

          SetTextColor(dc,   RGB(
255 , 255 , 255 ));

          BitBlt(dc,   
0 , 0 ,nWidthSrc,nHeightSrc,maskDC, 0 , 0 ,SRCAND);

 

          HDC   newMaskDC   
=    CreateCompatibleDC(NULL);

          HBITMAP   newMask;

          newMask   
=    CreateBitmap(nWidthDest,   nHeightDest,    1 ,

                                                                        GetDeviceCaps(newMaskDC,   BITSPIXEL),   NULL);

 

          
if    (newMask    ==    NULL)

          {

                  SelectObject(dc,   oldBitmap);

                  DeleteDC(dc);

                  SelectObject(maskDC,   oldMask);

                  DeleteDC(maskDC);

                    DeleteDC(newMaskDC);

                  DeleteObject(bitmap);          

                  DeleteObject(maskBitmap);  

                  
return     false ;

          }

 

          SetStretchBltMode(newMaskDC,   COLORONCOLOR);

          HBITMAP   oldNewMask   
=    (HBITMAP)   SelectObject(newMaskDC,   newMask);

          StretchBlt(newMaskDC,   
0 ,    0 ,   nWidthDest,   nHeightDest,   maskDC,    0 ,    0 ,

                                                                                              nWidthSrc,   nHeightSrc,   SRCCOPY);

 

          SelectObject(maskDC,   oldMask);

          DeleteDC(maskDC);

          DeleteObject(maskBitmap);  

 

          HDC   newImageDC   
=    CreateCompatibleDC(NULL);

          HBITMAP   newImage   
=    CreateBitmap(nWidthDest,   nHeightDest,    1 ,

                                                                        GetDeviceCaps(newMaskDC,   BITSPIXEL),   NULL);

 

          
if    (newImage    ==    NULL)

          {

                  SelectObject(dc,   oldBitmap);

                  DeleteDC(dc);

                  DeleteDC(newMaskDC);

                  DeleteObject(bitmap);          

                  
return     false ;

          }

 

          HBITMAP   oldNewImage   
=    (HBITMAP)SelectObject(newImageDC,   newImage);

          StretchBlt(newImageDC,   
0 ,    0 ,   nWidthDest,   nHeightDest,   dc,    0 ,    0 ,   nWidthSrc,

                                                                                                                    nHeightSrc,   SRCCOPY);

 

          SelectObject(dc,   oldBitmap);

          DeleteDC(dc);

          DeleteObject(bitmap);          

 

          BitBlt(   dcDest,   nXOriginDest,   nYOriginDest,   nWidthDest,   nHeightDest,

                                                                                                            newMaskDC,   
0 ,    0 ,   SRCAND);

 

          BitBlt(   dcDest,   nXOriginDest,   nYOriginDest,   nWidthDest,   nHeightDest,

                                                                                                      newImageDC,   
0 ,    0 ,   SRCPAINT);

 

          SelectObject(newImageDC,   oldNewImage);

          DeleteDC(newImageDC);

          SelectObject(newMaskDC,   oldNewMask);

          DeleteDC(newMaskDC);

          DeleteObject(newImage);      

          DeleteObject(newMask);        

 

          
return     true ;

}

你可能感兴趣的:(透明色)