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

    适用图片:同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 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, 11, 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, 00, nWidthDest, nHeightDest, hdcSrc, nXOriginSrc, nYOriginSrc, SRCCOPY);
     
        
    // 设置临时DC的透明色
        SetBkColor(hImageDC, crTransparent);

        
    // 生成透明区域为白色,其它区域为黑色的临时掩码DC的掩码位图
        
    // 位图来自临时DC
        BitBlt(hMaskDC, 00, nWidthDest, nHeightDest, hImageDC, 00, SRCCOPY);

        
    // 生成透明区域为黑色,其它区域保持不变的位图
        SetBkColor(hImageDC, RGB(0,0,0));
        SetTextColor(hImageDC, RGB(
    255,255,255));
        BitBlt(hImageDC, 
    00, nWidthDest, nHeightDest, hMaskDC, 00, SRCAND);

        
    // 透明部分保持屏幕不变,其它部分变成黑色
        SetBkColor(hdcDest,RGB(255,255,255));
        SetTextColor(hdcDest,RGB(
    0,0,0));
         BitBlt(hdcDest, nXOriginDest, nYOriginDest, nWidthDest, nHeightDest, hMaskDC, 
    00, SRCAND);

        
    // "或"运算,生成最终效果
        BitBlt(hdcDest, nXOriginDest, nYOriginDest, nWidthDest, nHeightDest, hImageDC, 00, 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, 11, 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, 00, nWidthDest, nHeightDest, hdcSrc, nXOriginSrc, nYOriginSrc, SRCCOPY);
     
        
    // 设置临时DC的透明色
        SetBkColor(hImageDC, crTransparent);

        
    // 生成透明区域为白色,其它区域为黑色的临时掩码DC的掩码位图
        
    // 位图来自临时DC
        BitBlt(hMaskDC, 00, nWidthDest, nHeightDest, hImageDC, 00, SRCCOPY);

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

        
         
        BitBlt(hdcDest, nXOriginDest, nYOriginDest, nWidthDest, nHeightDest, hMaskDC, 00, 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, 11, 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, 
    00, nWidthDest, nHeightDest, hdcSrc, nXOriginSrc, nYOriginSrc, SRCCOPY);
        }

        
    else
        ...
    {
            StretchBlt(hImageDC, 
    00, nWidthDest, nHeightDest, 
            hdcSrc, nXOriginSrc, nYOriginSrc, nWidthSrc, nHeightSrc, SRCCOPY);
        }

        
        
    // 设置透明色
        SetBkColor(hImageDC, crTransparent);

        
    // 生成透明区域为白色,其它区域为黑色的掩码位图
        BitBlt(hMaskDC, 00, nWidthDest, nHeightDest, hImageDC, 00, SRCCOPY);
        
        
    // 生成透明区域为黑色,其它区域保持不变的位图
        SetBkColor(hImageDC, RGB(0,0,0));
        SetTextColor(hImageDC, RGB(
    255,255,255));
        BitBlt(hImageDC, 
    00, nWidthDest, nHeightDest, hMaskDC, 00, SRCAND);

        
    // 透明部分保持屏幕不变,其它部分变成黑色
        SetBkColor(hdcDest,RGB(0xff,0xff,0xff));
        SetTextColor(hdcDest,RGB(
    0,0,0));
        BitBlt(hdcDest, nXOriginDest, nYOriginDest, nWidthDest, nHeightDest, hMaskDC, 
    00, SRCAND);
        
        
    // "或"运算,生成最终效果
        BitBlt(hdcDest, nXOriginDest, nYOriginDest, nWidthDest, nHeightDest, hImageDC, 00, 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, 00, nWidthDest, nHeightDest, hdcSrc, nXOriginSrc, nYOriginSrc, SRCCOPY);
         
    // 设置临时DC的透明色
        SetBkColor(hImageDC, crTransparent);
        
    // 生成透明区域为黑色,其它区域保持不变的位图
        SetBkColor(hImageDC, RGB(0,0,0));
        SetTextColor(hImageDC, RGB(
    255,255,255));
        BitBlt(hImageDC, 
    00, nWidthDest, nHeightDest, hdcMask, 00, SRCAND);
        
    // 透明部分保持屏幕不变,其它部分变成黑色
        SetBkColor(hdcDest,RGB(255,255,255));
        SetTextColor(hdcDest,RGB(
    0,0,0));
         BitBlt(hdcDest, nXOriginDest, nYOriginDest, nWidthDest, nHeightDest, hdcMask, 
    00, SRCAND);
         
    // "或"运算,生成最终效果
        BitBlt(hdcDest, nXOriginDest, nYOriginDest, nWidthDest, nHeightDest, hImageDC, 00, 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);
            ::DeleteDC(hmemDC);

            
    return hrgn;
        
    }

     部分摘自:http://blog.csdn.net/xuweiqun/archive/2006/11/11/1378714.aspx,其中还补充了一些平时用到的方法

  • 相关阅读:
    SQL server 日期格式转换style 对应码
    postman的使用方法详解!最全面的教程
    港澳台身份证小结
    使用设置自定义对话框的大小,位置,样式以及设置在安卓桌面上弹出对话框
    android自定义Activity窗口大小(theme运用)
    C#调用RabbitMQ实现消息队列
    C# http请求带请求头部分
    Android如何屏蔽home键和recent键
    针对jquery的优化方法,你知道几条
    试图从目录中执行 CGI、ISAPI 或其他可执行程序
  • 原文地址:https://www.cnblogs.com/Jianchidaodi/p/557595.html
Copyright © 2020-2023  润新知