zoukankan      html  css  js  c++  java
  • C++ 透明位图

    在开发界面及棋牌游戏过程中,需要很多镂空的图片,而且图片形式一般比较固定.
    所以封装了几种常见的镂空方法.

    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类型
          );

    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 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 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);

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

        BitBlt(hdcDest, nXOriginDest, nYOriginDest, nWidthDest, nHeightDest, hImageDC, 0, 0, SRCINVERT);
        // 清理、恢复    
        SelectObject(hImageDC, hOldImageBMP);
        DeleteDC(hImageDC);
        SelectObject(hMaskDC, hOldMaskBMP);
        DeleteDC(hMaskDC);
        DeleteObject(hImageBMP);
        DeleteObject(hMaskBMP);
    }

    //用于没有掩码图,只有指定透明色,可以进行伸缩
    //方法一:
    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类型
                         )
    {
        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 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类型
                         )
    {
      
          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;
    }

    指定掩码图,和掩码图属于不同图片
    void 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 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 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);
       

  • 相关阅读:
    Jmeter逻辑控制器
    python学习笔记——%占位符的使用
    python学习笔记——生成随机数
    python学习笔记——变量的规则
    loadrunner11中HTTP/HTML的HTML-base script的两种script type有什么区别?
    loadrunner11如何实时查看脚本的运行情况?
    loaderunner11回放脚本时如何设置【运行时行为】?
    appium学习笔记之——popupwindow控件元素无法定位
    Chrome、Firefox、IE等浏览器驱动diver程序存放目录
    npm方式安装appium环境所遇到的各种问题
  • 原文地址:https://www.cnblogs.com/zhixing/p/2249058.html
Copyright © 2011-2022 走看看