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

    画透明位图

          我们在进行程序的界面设计时,常常希望将位图的关键部分,也既是图像的前景显示在界面上,而将位图的背景隐藏起来,将位图与界面很自然的融合在一起,本文介绍了透明位图的制作知识,并将透明位图在一个对话框中显示了出来。 

     

     

    一、实现方法

      绘制"透明"位图是指绘制某一位图中除指定颜色外的其余部分,我们称这种颜色为"透明色"。通过将位图的背景色指定为"透明色",在绘制时,不绘制这部分背景,而仅绘制图像,这样就可以将位图中图像透明地绘制到窗口上。 

      绘制"透明"位图的关键是创建一个"掩码"位图(mask bitmap),"掩码"位图是一个单色位图,它是位图中图像的一个单色剪影。在Windows编程中,绘图都要用到设备描述表,我们需创建两个内存设备描述表:位图设备描述表(image DC)和"掩码"位图设备描述表(mask DC)。位图设备描述表用来装入位图,而"掩码"位图设备描述表用来装入"掩码"位图。在"掩码"位图设备描述表中制作"掩码"位图的方式是:先创建一个单色的Bitmap,装入mask DC,然后,以"SRCCOPY"的方式将装有位图的位图设备描述表绘制(BitBlt)到mask DC上。这样,mask DC的显示平面中的位图即是"掩码"位图。 

      一般情况下,绘制"透明"位图的实际操作步骤如下:

    1、设置待显示位图的背景颜色,也就是设置我们希望透明显示的位图颜色;

    2、位图设备描述表以"SRCINVERT"的方式绘制(BitBlt)到显示设备描述表上;

    3、"掩码"位图设备描述表以"SRCAND"的方式绘制(BitBlt)到显示设备描述表上;

    4、再将位图设备描述表以"SRCINVERT"的方式绘制(BitBlt)到显示设备描述表上。这样除"透明色"外的其余位图部分(图像部分)就被绘制到窗口上了。

      上述操作中需要用到的位图显示函数BitBlt()的原型和说明如下:

    BOOL BitBlt( int x, int y, int nWidth, int nHeight, CDC* pSrcDC, int xSrc, 
    int ySrc, DWORD dwRop );

      其中,参数int x表示贴到目的地的左上角X坐标;int y表示/贴到目的地的左上角Y坐标;int nWidth表示贴到目的地的区域宽度;int nHeight表示贴到目的地的区域高度;CDC* pSrcDC表示存储源位图的设备描述表;int xSrc表示源位图的左上角X坐标;int ySrc表示源位图的左上角Y坐标;DWORD dwRop为柵格运算标志(ROP),它明确定义了如何将源文件、目标文件和模式(由现在选出的刷子画笔定义)的位组合去形成一个目标文件。对于所有的设备类型,光栅操作(ROP)只简单地在表示位图颜色的每一个bit位上展开相关操作而不考虑他们的实际意义。微软为位图的光栅操作提供了多种方法,开发人员可以使用不同的组合得到想要的特殊效果。由于篇幅的限制,本文只讨论四种常用的光栅操作:

    操作方式 

    运算方式 

    效果 

    SRCCOPY  

    src 

    直接将源位图拷贝到目的设备上。 

    SRCAND

    src AND dest

    将目标文件中对应于源文件黑色区域的部分变黑,将对应于白色区域的部分留着不动。

    SRCINVERT

    src XOR dest

    将源插入到目标。二次使用时,将目标恢复到它原来的状态。在某种条件下可以代替SRCPAINT 操作。

    SRCPAINT

    src OR dest

    将源文件中的白色区域刷到目标文件中。源中的黑色区域不转换到目标中。

      这里补充说明一点,显示位图的背景颜色可以通过PhotoShop等图像处理软件获取,当然,也可以通过读取位图上特殊位置上的像素点的颜色来获取,前者实现起来比较方便,后者稍微麻烦一些,这可以根据个人爱好自由选择。

    ----------------------------------------------------------------------------------------------------------------------------------------------------------------

    二、Delphi下的实现

    procedure DrawTransBitmap(hdcDest: HDC;      // 目标DC
                        nXOriginDest,            // 目标X偏移
                        nYOriginDest,            // 目标Y偏移
                        nWidthDest,              // 目标宽度
                        nHeightDest: Integer;    // 目标高度
                        hdcSrc: HDC;             // 源DC
                        nXOriginSrc,             // 源X起点
                        nYOriginSrc: Integer;    // 源Y起点
                        crTransparent: TColor    // 透明色
                        );
    var
      hOldImageBMP, hImageBMP, hOldMaskBMP, hMaskBMP: HBITMAP;
      hImageDC, hMaskDC: HDC;
    begin
        hImageBMP := CreateCompatibleBitmap(hdcDest, nWidthDest, nHeightDest);    // 创建兼容位图
        hMaskBMP := CreateBitmap(nWidthDest, nHeightDest, 1, 1, NIL);            // 创建单色掩码位图
        hImageDC := CreateCompatibleDC(hdcDest);//临时DC
        hMaskDC := CreateCompatibleDC(hdcDest);//临时掩码DC
        hOldImageBMP := SelectObject(hImageDC, hImageBMP);
        hOldMaskBMP := 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);
    end;

    -------------------------------------------------------------------------------------------------------------

    看一下Delphi自己的封装

    procedure TForm1.btn1Click(Sender: TObject);

    var

      Bitmap : TBitMap;
    begin
      Bitmap := TBitmap.Create;
      Bitmap.Width := 200;
      Bitmap.Height := 180;
      try
        with Bitmap do begin
          Bitmap.Canvas.Rectangle(0, 0,   Bitmap.Width, Bitmap.Height);
          Transparent := True;
          TransParentColor := clwhite;
          Form1.Canvas.Draw(0,0,BitMap);
        end;
      finally
        Bitmap.Free;

      end;

    ------------------------------------------------------------------------------------------------------------------

    三、VC下的实现

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

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

    http://blog.csdn.net/shuaihj/article/details/8551322

  • 相关阅读:
    TCP/IP协议栈之QEMU
    FreeRTOS-Plus-CLI中添加一个自己的命令行
    FreeRTOS A57
    log日志库
    函数解读:ioremap / ioremap_nocache / ioremap_wc / ioremap_wt
    Makefile 使用小结
    41. 缺失的第一个正数(First Missing Positive)
    42. 接雨水(Trapping Rain Water)
    关于C++内联和静态成员函数的问题
    C++11 线程并发问题
  • 原文地址:https://www.cnblogs.com/findumars/p/5345647.html
Copyright © 2011-2022 走看看