您的位置:首页 > 其它

获得位图非屏蔽色/屏蔽色区域的算法

2010-02-13 08:28 190 查看
// 获得图片区域
void CImgBitmap::GetImageRgn(CRgn&		fulRgn,
COLORREF	clrTrans		/*= RGB(255, 0, 255)*/,
BOOL		bCombineTrans	/*= FALSE*/,
int		nCombineMode	/*= RGN_OR*/,
LPPOINT	lpPoint			/*= NULL*/)
{
if( IsNull() ) return ;

if( !fulRgn.m_hObject )
{
// 创建总区域,初始region为0
fulRgn.CreateRectRgn(0, 0, 0, 0);
}
// 创建图片区域,初始region为0
CRgn rgnImg;
rgnImg.CreateRectRgn(0, 0, 0, 0);

// 申请位图数据内存块
DWORD		dwWidth		= GetWidth();
DWORD		dwHeight	= GetHeight();
DWORD		dwBufBits	= dwWidth * dwHeight;
COLORREF*	btBufBits	= new COLORREF[dwBufBits];
dwBufBits	*= sizeof(COLORREF) / sizeof(BYTE);
// 获得位图数据
GetBitmapBits(dwBufBits, btBufBits);

// 判断图像像素点
for(int y = 0; y < (int)dwHeight; y++)
{
CRgn rgnTemp;
int iX = 0;
do
{
if( bCombineTrans )
{
// 跳过非透明色找到下一个透明色的点
while( iX < (int)dwWidth && btBufBits[y * dwWidth + iX] != clrTrans )
iX++;
// 记住这个起始点
int iLeftX = iX;
// 寻找下个非透明色的点
while( iX < (int)dwWidth && btBufBits[y * dwWidth + iX] == clrTrans )
iX++;
if( iLeftX == iX )
continue;
// 创建一个包含起点与终点间高为1像素的临时"region"
rgnTemp.CreateRectRgn(iLeftX, y, iX, y+1);
}
else
{
// 跳过透明色找到下一个非透明色的点
while( iX < (int)dwWidth && btBufBits[y * dwWidth + iX] == clrTrans )
iX++;
// 记住这个起始点
int iLeftX = iX;
// 寻找下个透明色的点
while( iX < (int)dwWidth && btBufBits[y * dwWidth + iX] != clrTrans )
iX++;
if( iLeftX == iX )
continue;
// 创建一个包含起点与终点间高为1像素的临时"region"
rgnTemp.CreateRectRgn(iLeftX, y, iX, y+1);
}
// 合并到图片"region"
rgnImg.CombineRgn(&rgnImg, &rgnTemp, RGN_OR);
// 删除临时"region",否则下次创建时和出错
rgnTemp.DeleteObject();
}while( iX < (int)dwWidth );
} // END for(int y = 0; ...) END

// 清理内存块
delete [] btBufBits;

// 偏移图片区域
if( lpPoint )
rgnImg.OffsetRgn(*lpPoint);
// 合并主区域
fulRgn.CombineRgn(&fulRgn, &rgnImg, nCombineMode);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: