原文章地址:http://hi.baidu.com/belovedjuan/item/f5611eba57fafbf463388e7c
抠图原理:需要处理的图片都是具有单色背景的图片(否则,这种情况下就没有任何的意义)。假如图片的背景色是黑色,编程的主要工作就是把图中的非黑色部分抠出,形成一个区域。“抠”的原理就是:从图片的左上角(0,0)开始,按照从上到下,从左到右的顺序形成长宽都为1的N(N=图片长 X 图片宽)个矩形(实际上是一个像素),如果矩形中含有背景色黑色,将之除去,对剩下的矩形全都使用CreateRectRgnIndirect建立器若干个区域,由于这些区域都不包含黑色(实际上代表着图片主要内容),所以,对这些区域进行合成就形成了主画面的区域,这就是“抠”出主画面区域的关键思路所在。
void CGDIPlusdemoView::OnRegionFromBitmap()
{
Graphics graphsics(this->m_hWnd);
//绘制样本图片
Bitmap bmp(AfxGetInstanceHandle(),(LPWSTR)MAKEINTRESOURCE(IDB_SCORE));
graphsics.DrawImage(&bmp,0,0);
//绘图平面右移,示意使用GDI生成区域
graphsics.TranslateTransform(bmp.GetWidth()+10,0);
CDC*pDC=GetDC();
CDC memDC;
CBitmap bmpScore;
CBitmap*pOldMemBmp=NULL;
COLORREF PixlColor,BackGroudColor;
CRect cRect;
int x,y;
GetClientRect(&cRect);
CPoint TopLeft=cRect.TopLeft();
CRgn ScoreRGN,rgnTemp;
//载入图片
bmpScore.LoadBitmap(IDB_SCORE);
BITMAP bmInfo;
bmpScore.GetObject(sizeof(bmInfo),&bmInfo);
CRect picWnd=CRect(TopLeft,CSize(bmInfo.bmWidth,bmInfo.bmHeight));
memDC.CreateCompatibleDC(pDC);
pOldMemBmp=memDC.SelectObject(&bmpScore);
//指明背景色,图片的第一个像素值
BackGroudColor=memDC.GetPixel(0,0);
//创建一个与位图大小相等的区域
ScoreRGN.CreateRectRgn(0,0,picWnd.Width(),picWnd.Height());
//获取图片的每一个像素值
for (x=0;x<=picWnd.Width();x++)
{
for (y=0;y<=picWnd.Height();y++)
{
PixlColor=memDC.GetPixel(x,y);
if (PixlColor==BackGroudColor)
{
//如果像素不包含蓝色,创建一个大小为1的区域
rgnTemp.CreateRectRgn(x,y,x+1,y+1);
//将这些区域相加,形成主画面的区域
ScoreRGN.CombineRgn(&ScoreRGN,&rgnTemp,RGN_XOR);
rgnTemp.DeleteObject();
}
}
}
//恢复设备环境
memDC.SelectObject(pOldMemBmp);
//从CRGN中创建区域
Region region(ScoreRGN);
//填充区域
graphsics.FillRegion(&SolidBrush(Color::Blue),®ion);
}