图片镂空算法集合

在开发界面及棋牌游戏过程中,需要很多镂空的图片,而且图片形式一般比较固定.

所以封装了几种常见的镂空方法.

1. 用于没有掩码图,只有指定透明色,不进行伸缩

void  DrawTransBitmap( HDC hdcDest,             //  目标DC
                                            int  nXOriginDest,        //  目标X偏移
                                             int  nYOriginDest,        //  目标Y偏移
                                             int  nWidthDest,          //  目标宽度
                                             int  nHeightDest,         //  目标高度
                                            HDC hdcSrc,               //  源DC
                                            int  nXOriginSrc,          //  源X起点
                                             int  nYOriginSrc,          //  源Y起点
                                            COLORREF crTransparent  //  透明色,COLORREF类型
                                        );

适用图片:

2. 用于没有掩码图,只有指定透明色,可以进行伸缩

  void  DrawTransBitmap( 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,       //  源高度
                                             COLORREF crTransparent   //  透明色,COLORREF类型
      );

适用图片:同1,可拉伸

3.指定掩码图,和掩码图属于不同图片

  void  DrawTransBitmap( HDC hdcDest,         //  目标DC
                                              int  nXOriginDest,    //  目标X偏移
                                              int  nYOriginDest,    //  目标Y偏移
                                              int  nWidthDest,        //  目标宽度
                                              int  nHeightDest,     //  目标高度
                                             HDC hdcSrc,          //  源DC
                                             HDC hdcMask,        // 掩码DC
                                              int  nXOriginSrc,      //  源X起点
                                              int  nYOriginSrc,      //  源Y起点
                                            COLORREF crTransparent   //  透明色,COLORREF类型
                                          );

适用图片:   和

4.指定图片和掩码图同属于一张图片

void  DrawTransBitmap(HDC hDC, 
                                          
int  nPosX, 
                                           
int  nPosY,
                                           
int  nCX, 
                                           
int  nCY, 
                                           HBITMAP hObj
                                           );

适用图片:

5.得到位图HRGN

   HRGN CreateBitmapRgn( int  nWidth, int  nHeight,HBITMAP hbmp,COLORREF cTrans);

适用图片:

以下是完整代码

// 用于没有掩码图,只有指定透明色,不进行伸缩
void  CCommon::DrawTransBitmap( HDC hdcDest,       //  目标DC
                     int  nXOriginDest,    //  目标X偏移
                     int  nYOriginDest,    //  目标Y偏移
                     int  nWidthDest,      //  目标宽度
                     int  nHeightDest,     //  目标高度
                    HDC hdcSrc,          //  源DC
                     int  nXOriginSrc,     //  源X起点
                     int  nYOriginSrc,     //  源Y起点
                    COLORREF crTransparent   //  透明色,COLORREF类型
                    )
...
{
    HBITMAP hOldImageBMP, hImageBMP 
=  CreateCompatibleBitmap(hdcDest, nWidthDest, nHeightDest);     //  创建兼容位图
    HBITMAP hOldMaskBMP, hMaskBMP  =  CreateBitmap(nWidthDest, nHeightDest,  1 1 , NULL);             //  创建单色掩码位图
    HDC        hImageDC  =  CreateCompatibleDC(hdcDest); // 临时DC 
    HDC        hMaskDC  =  CreateCompatibleDC(hdcDest); // 临时掩码DC 
    hOldImageBMP  =  (HBITMAP)SelectObject(hImageDC, hImageBMP);
    hOldMaskBMP 
=  (HBITMAP)SelectObject(hMaskDC, hMaskBMP);

    
//  将源DC中的位图拷贝到临时DC中,源DC已经载入位图
     BitBlt(hImageDC,  0 0 , nWidthDest, nHeightDest, hdcSrc, nXOriginSrc, nYOriginSrc, SRCCOPY);
 
    
//  设置临时DC的透明色
    SetBkColor(hImageDC, crTransparent);

    
//  生成透明区域为白色,其它区域为黑色的临时掩码DC的掩码位图
    
//  位图来自临时DC
    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);
}
 


// 用于没有掩码图,只有指定透明色,可以进行伸缩
void  CCommon::DrawTransBitmap( 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,      //  源高度
                     COLORREF 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( 0xff , 0xff , 0xff ));
    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);
    
}



指定掩码图,和掩码图属于不同图片
void  CCommon::DrawTransBitmap( HDC hdcDest,       //  目标DC
                     int  nXOriginDest,    //  目标X偏移
                     int  nYOriginDest,    //  目标Y偏移
                     int  nWidthDest,      //  目标宽度
                     int  nHeightDest,     //  目标高度
                    HDC hdcSrc,          //  源DC
                    HDC hdcMask,
                    
int  nXOriginSrc,     //  源X起点
                     int  nYOriginSrc,     //  源Y起点
                    COLORREF crTransparent   //  透明色,COLORREF类型
                    )
...
{

    HBITMAP hOldImageBMP, hImageBMP 
=  CreateCompatibleBitmap(hdcDest, nWidthDest, nHeightDest);     //  创建兼容位图
     HDC        hImageDC  =  CreateCompatibleDC(hdcDest); // 临时DC 
     hOldImageBMP  =  (HBITMAP)SelectObject(hImageDC, hImageBMP);
 
    
//  将源DC中的位图拷贝到临时DC中,源DC已经载入位图
     BitBlt(hImageDC,  0 0 , nWidthDest, nHeightDest, hdcSrc, nXOriginSrc, nYOriginSrc, SRCCOPY);
     
//  设置临时DC的透明色
    SetBkColor(hImageDC, crTransparent);
    
//  生成透明区域为黑色,其它区域保持不变的位图
    SetBkColor(hImageDC, RGB( 0 , 0 , 0 ));
    SetTextColor(hImageDC, RGB(
255 , 255 , 255 ));
    BitBlt(hImageDC, 
0 0 , nWidthDest, nHeightDest, hdcMask,  0 0 , SRCAND);
    
//  透明部分保持屏幕不变,其它部分变成黑色
    SetBkColor(hdcDest,RGB( 255 , 255 , 255 ));
    SetTextColor(hdcDest,RGB(
0 , 0 , 0 ));
     BitBlt(hdcDest, nXOriginDest, nYOriginDest, nWidthDest, nHeightDest, hdcMask, 
0 0 , SRCAND);
     
//  "或"运算,生成最终效果
    BitBlt(hdcDest, nXOriginDest, nYOriginDest, nWidthDest, nHeightDest, hImageDC,  0 0 , SRCPAINT);
    
//  清理、恢复    
    SelectObject(hImageDC, hOldImageBMP);
    DeleteDC(hImageDC);
    DeleteObject(hImageBMP);
}
 

指定图片和掩码图同属于一张图片
void  CCommon::DrawTransBitmap(HDC hDC,  int  nPosX,  int  nPosY,  int  nCX,  int  nCY, HBITMAP hObj)
...
{
    HDC hMemDC
=  CreateCompatibleDC(hDC);
    HBITMAP hOldBMP
= (HBITMAP)::SelectObject(hMemDC,hObj);
      BitBlt(hDC,nPosX,nPosY,nCX,nCY,    hMemDC,nCX,
0 ,SRCAND);
    BitBlt(hDC,nPosX,nPosY,nCX,nCY,    hMemDC,
0 , 0 ,SRCPAINT);
    SelectObject(hMemDC,hOldBMP);
    DeleteDC(hMemDC);

}
  

HRGN CCommon::CreateBitmapRgn(
int  nWidth, int  nHeight,HBITMAP hbmp, COLORREF TransColor)
...
{

        HDC  hmemDC;
        
// 创建与传入DC兼容的临时DC
        hmemDC  =  ::CreateCompatibleDC(NULL);
        
        HBITMAP hOldBmp 
=  (HBITMAP)::SelectObject(hmemDC,hbmp);
        
        
        
// 创建总的窗体区域,初始region为0
        HRGN hrgn;
        hrgn 
=  ::CreateRectRgn( 0 , 0 , 0 , 0 );
           
        
        
int  y;
        
for (y = 0 ;y < nHeight ;y ++ )
        ...
{
            HRGN rgnTemp; 
// 保存临时region
            
            
int  iX  =   0 ;
            
do
            ...
{
                
// 跳过透明色找到下一个非透明色的点.
                 while  (iX  <  nWidth   &&  ::GetPixel(hmemDC,iX, y)  ==  TransColor)
                    iX
++ ;
                
                
// 记住这个起始点
                 int  iLeftX  =  iX;
                
                
// 寻找下个透明色的点
                 while  (iX  <  nWidth   &&  ::GetPixel(hmemDC,iX, y)  !=  TransColor)
                    
++ iX;
                
                
// 创建一个包含起点与重点间高为1像素的临时“region”
                rgnTemp = ::CreateRectRgn(iLeftX, y, iX, y + 1 );
                
                
// 合并到主"region".
                CombineRgn( hrgn,hrgn,rgnTemp, RGN_OR);
                
                
// 删除临时"region",否则下次创建时和出错
                ::DeleteObject(rgnTemp);
            }
while (iX  < nWidth );
            iX 
=   0 ;
        }

        

        ::SelectObject(hmemDC,hOldBmp);
        ::DeleteDC(hmemDC);

        
return  hrgn;
    
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值