51Testing软件测试论坛

 找回密码
 (注-册)加入51Testing

QQ登录

只需一步,快速开始

微信登录,快人一步

手机号码,快捷登录

查看: 3329|回复: 1
打印 上一主题 下一主题

图片镂空算法集合[图]

[复制链接]
  • TA的每日心情
    慵懒
    2015-1-8 08:46
  • 签到天数: 2 天

    连续签到: 1 天

    [LV.1]测试小兵

    跳转到指定楼层
    1#
    发表于 2007-12-13 10:26:27 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
    在开发界面及棋牌游戏过程中,需要很多镂空的图片,而且图片形式一般比较固定.
    所以封装了几种常见的镂空方法.
    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:rawTransBitmap( 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:rawTransBitmap( 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:rawTransBitmap( 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:rawTransBitmap(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",否则下次创建时和出错
                    :eleteObject(rgnTemp);
                }
    while(iX <nWidth );
                iX
    =
    0;
            }

            

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

            
    return hrgn;
       
    }

    分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
    收藏收藏
    回复

    使用道具 举报

    该用户从未签到

    2#
    发表于 2007-12-13 13:05:12 | 只看该作者
    强劲的技术贴阿
    回复 支持 反对

    使用道具 举报

    本版积分规则

    关闭

    站长推荐上一条 /1 下一条

    小黑屋|手机版|Archiver|51Testing软件测试网 ( 沪ICP备05003035号 关于我们

    GMT+8, 2024-11-25 18:26 , Processed in 0.081389 second(s), 28 queries .

    Powered by Discuz! X3.2

    © 2001-2024 Comsenz Inc.

    快速回复 返回顶部 返回列表