图片镂空算法集合[图]

news/2024/7/6 1:51:14

在开发界面及棋牌游戏过程中,需要很多镂空的图片,而且图片形式一般比较固定.

所以封装了几种常见的镂空方法.

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::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  CCommon::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  CCommon::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  CCommon::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 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",否则下次创建时和出错
                ::DeleteObject(rgnTemp);
            }
while(iX <nWidth );
            iX 
= 0;
        }

        

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

        
return hrgn;
    
}

 

 





http://www.niftyadmin.cn/n/3647494.html

相关文章

如何调试MFC中的内存泄漏[转帖]

首先&#xff0c;应该是MFC报告我们发现内存泄漏。注意&#xff1a;要多运行几次&#xff0c;以确定输出的内容不变&#xff0c;特别是{}之间的数值&#xff0c;不能变&#xff0c;否则下面的方法就不好用了。我们来看看&#xff1a;F:/CodeSample/Test/TestPipe/LeakTest/Main…

Spring事务是如何传播的?真香系列

前言 互联网时代&#xff0c;瞬息万变。一个小小的走错&#xff0c;就有可能落后于别人。我们没办法去预测任何行业、任何职业未来十年会怎么样&#xff0c;因为未来谁都不能确定。只能说只要有互联网存在&#xff0c;程序员依然是个高薪热门行业。只要跟随着时代的脚步&#…

【Leetcode】739. Daily Temperatures

题目地址&#xff1a; https://leetcode.com/problems/daily-temperatures/ 题目大意是&#xff0c;对于数组中每个数字&#xff0c;找出右边第一个比它大的数字&#xff0c;记录下标的差最后返回。典型单调栈的应用。维护一个单调下降的栈&#xff0c;如果栈空或者栈顶大于等…

DLL(Dynamic Link Libraries)专题[转帖]

原帖地址:http://www.microsoft.com/china/community/program/originalarticles/techdoc/dll.mspxDLL(Dynamic Link Libraries)专题目录引言 调用方式 MFC中的DLL DLL入口函数 关于约定 关于DLL的函数 模块定义文件(.DEF) DLL程序和调用其输出函数的程序的关系 作者引言比较大的…

【Leetcode】704. Binary Search

题目地址&#xff1a; https://leetcode.com/problems/binary-search/ 给定一个长nnn的升序数组AAA&#xff0c;返回某个给定数ttt的下标&#xff0c;如果不存在则返回−1-1−1。 二分。代码如下&#xff1a; class Solution {public:int search(vector<int>& a, …

Spring是怎样巧用三级缓存解决循环依赖的?灵魂拷问

前言 目前绝大部分的Java程序员都是处于增删改查的阶段&#xff0c;但是到了这个阶段后就应该考虑下一个层次的突破了&#xff0c;总不能做一辈子的crud吧… **以目前IT行业的发展趋势以及就业情况来看&#xff0c;**市场早已经不缺初级开发了&#xff0c;对于中高级开发人才…

【Leetcode】74. Search a 2D Matrix

题目地址&#xff1a; https://leetcode.com/problems/search-a-2d-matrix/ 给定一个mnm\times nmn的矩阵AAA&#xff0c;每行单调上升&#xff0c;并且每行的末项都小于下一行的首项。另给定一个数&#xff0c;问这个数是否在矩阵里。 思路是二分法&#xff0c;可以将整个矩…

StringBoot编程式事务与声明式事务,给大家安排上!

一、前言 长文警告&#xff0c;事实上我不愿意写太长的文章&#xff0c;一面是太冗余&#xff0c;一方面读者容易疲倦&#xff0c;但是只要是涉及到源码级别的&#xff0c;就肯定篇幅不短&#xff0c;因为太短肯定没意义也解释不清楚&#xff0c;但是相信&#xff0c;耐心看完这…