life02

  C++博客 :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理 ::
  197 随笔 :: 3 文章 :: 37 评论 :: 0 Trackbacks
你可以先将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;

}

posted on 2012-03-21 16:58 life02 阅读(536) 评论(0)  编辑 收藏 引用 所属分类: Android开发

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理