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

  • 相关阅读:
    工作中遇到的java 内存溢出,问题排查
    java线上内存溢出问题排查步骤
    性能测试-java内存溢出问题排查
    164 01 Android 零基础入门 03 Java常用工具类01 Java异常 04 使用try…catch…finally实现异常处理 04 终止finally执行的方法
    163 01 Android 零基础入门 03 Java常用工具类01 Java异常 04 使用try…catch…finally实现异常处理 03 使用多重catch结构处理异常
    162 01 Android 零基础入门 03 Java常用工具类01 Java异常 04 使用try…catch…finally实现异常处理 02 使用try-catch结构处理异常
    161 01 Android 零基础入门 03 Java常用工具类01 Java异常 04 使用try…catch…finally实现异常处理 01 try-catch-finally简介
    160 01 Android 零基础入门 03 Java常用工具类01 Java异常 03 异常处理简介 01 异常处理分类
    159 01 Android 零基础入门 03 Java常用工具类01 Java异常 02 异常概述 02 异常分类
    158 01 Android 零基础入门 03 Java常用工具类01 Java异常 02 异常概述 01 什么是异常?
  • 原文地址:https://www.cnblogs.com/findumars/p/5345647.html
Copyright © 2011-2022 走看看