位图转区域

大狗狗 2007-12-03 10:21:38
在网上看到一段位图转区域的代码,实在看不明白:

"创建一个区域是调用SDK 的ExtCreateRegion 来实现( MFC 中的对应函数为CRgn::CreateFromData)。这个函数是通过提供一个矩形数组, 来创建一个由这些矩形组成的区域。"

CDib m_dib ;
CRgn m_rgn ;
COLORREF m_dwColorKey = 0x0000ff; // 透明色, 纯蓝

BOOL CAswDlg::CreateRegionFromBmp( LPCSTR lpsFName )
{
// 读入位图 
if( !m_dib.Open( lpsFName ) )
   return FALSE ;

SIZE dibsize ;

// 获取位图尺寸
dibsize = m_dib.GetSize( ) ;

int i , j ;
BOOL bkey ;
int iCount = 0 ;

// 统计需要的矩形个数
for( i = 0 ; i < dibsize.cy ; i ++)
{
  bkey = TRUE ;
  for( j = 0 ; j < dibsize.cx ; j ++)
  {
  if( m_dib.GetPixel( j , i ) == m_dwColorKey )
     {
        bkey = TRUE ;     }
     else
     {
        if( bkey )        {
          iCount ++;
        }
        bkey = FALSE ;     }
  }
}
由于 bkey 的存在,我实在搞不懂上面那段代码的逻辑,下面的代码也就看不下去了. bkey 起什么作用啊,这里面包含了什么原理?
BYTE *pData ;
RGNDATA *pRgnData ;
RECT *pRect ;
int iIndex = 0 ;

pData = new BYTE[ sizeof
( RGNDATAHEADER ) +sizeof( RECT ) *iCount ] ;
pRgnData = ( RGNDATA *)pData ;
pRect = ( RECT *)( pData +sizeof( RGNDATAHEADER ) ) ;
pRgnData ->rdh.dwSize =sizeo(RGNDATAHEADER ) ;
pRgnData ->rdh.iType   =RDH_RECTANGLES ;
pRgnData ->rdh.nCount  = iCount ;
pRgnData ->rdh.nRgnSize = sizeof( RECT ) *iCount ;
pRgnData ->rdh.rcBound.left     = 0 ;
pRgnData ->rdh.rcBound.top     = 0 ;
pRgnData ->rdh.rcBound.right    =dibsize.cx ;
pRgnData ->rdh.rcBound.bottom = dibsize.cy ;
   
int iLeft = 0 ;
for( i = dibsize.cy -1 ; i >= 0 ; i --)
// 因为Bitmap 位图在Y 方向是颠倒
 的所以要从底部开始
{
    bkey = TRUE ;
    iLeft = -1 ;
    for( j = 0 ; j < dibsize.cx ; j ++)
    {
    if( m_dib.GetPixel( j , i ) == m_dwColorKey )
    {
      if( !bkey )
      {
      pRect[ iIndex ].left = iLeft ;
      pRect[ iIndex ].right = j ;
      pRect[ iIndex ].top = dibsize.cy -i -1 ;
      pRect[iIndex].bottom = dibsize.cy -i;
      bkey = TRUE ;
      iIndex ++;
      iLeft = -1 ;
      }
    }
       else
       {
          if( bkey )
          {
            iLeft = j ;
            bkey = FALSE ;
          }
       }
    }

    if( iLeft >= 0 )
    {
      pRect[ iIndex ].left = iLeft ;
      pRect[ iIndex ].right = dibsize.cx ;
      pRect[ iIndex ].top = i ;
      pRect[ iIndex ].bottom = i ;
      iIndex ++;
    }
}
   BOOL br = m_rgn.CreateFromData
( NULL , sizeof( RGNDATAHEADER ) +sizeof
( RECT ) *iCount , pRgnData ) ;
   return br ;
}
...全文
72 4 打赏 收藏 转发到动态 举报
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
大狗狗 2007-12-04
  • 打赏
  • 举报
回复
感谢三位朋友的回贴!
zxbstrong 2007-12-03
  • 打赏
  • 举报
回复
针对每一行像素,刚开始bKey为TRUE,然后遇到一个非透明像素,即然是非透明像素,那么要使用一个矩形来描述,
iCount++,这个矩形直到遇到一个透明像素,才确定了宽度...
feng1976 2007-12-03
  • 打赏
  • 举报
回复
恰好搜到了这个例子

我猜可能是这样:
在一个图像上,找透明点,把这些点扩大成一个矩形,所有这些电组成一个数组
然后,传给CreateFromData,CreateFromData根据这些矩形,找到一个边界,并且封闭起来,得到区域
feng1976 2007-12-03
  • 打赏
  • 举报
回复
bKey是为了统计蓝色也就是透明色象素的个数

后边创建RGNDATA的时候用到了

16,472

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Web++
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

试试用AI创作助手写篇文章吧