VC++ Gdiplus::Bitmap抠图

void SetBackgroundMaskImage(LPCTSTR lpszImageName)
{
	COLORREF crAlpha = RGB(255, 0, 0);
	Gdiplus::Bitmap* pBkgrMaskBitmap = CImageFactory::getSingletonPtr()->GetSkinItemImage(lpszImageName);

	struct PixelData
	{
		BYTE B;
		BYTE G;
		BYTE R;
		BYTE A;
	};

	HRGN hRgn = NULL;
	if (pBkgrMaskBitmap)
	{
		//if (Gdiplus::IsAlphaPixelFormat((Gdiplus::PixelFormat)pBkgrMaskBitmap->GetPixelFormat()))
		{
			Gdiplus::BitmapData bitmapData;
			Gdiplus::Rect rcBitmap(0, 0, pBkgrMaskBitmap->GetWidth(), pBkgrMaskBitmap->GetHeight());
			Gdiplus::Status status = pBkgrMaskBitmap->LockBits(&rcBitmap, Gdiplus::ImageLockModeRead, pBkgrMaskBitmap->GetPixelFormat(), &bitmapData);
			if (status == Gdiplus::Ok)
			{
				#define ALLOC_UNIT	200
				DWORD maxRects = ALLOC_UNIT;
				HANDLE hData = GlobalAlloc(GMEM_MOVEABLE, sizeof(RGNDATAHEADER) + (sizeof(RECT) * maxRects));
				RGNDATA *pData = (RGNDATA *)GlobalLock(hData);
				pData->rdh.dwSize = sizeof(RGNDATAHEADER);
				pData->rdh.iType = RDH_RECTANGLES;
				pData->rdh.nCount = pData->rdh.nRgnSize = 0;
				SetRect(&pData->rdh.rcBound, MAXLONG, MAXLONG, 0, 0);
				int nBitsPixel = GetPixelFormatSize(pBkgrMaskBitmap->GetPixelFormat()) >> 3;
				int nLinesize = pBkgrMaskBitmap->GetWidth() * nBitsPixel;
				int nOffset = bitmapData.Stride - bitmapData.Width * nBitsPixel;
				PixelData* pPixel = (PixelData*)bitmapData.Scan0;
				for (int y = 0; y < bitmapData.Height; y++)
				{
					for (int x = 0; x < bitmapData.Width; x++)
					{
						int x0 = x;
						while (x < bitmapData.Width)
						{
							//if (pPixel->R==GetRValue(crAlpha) && pPixel->G == GetGValue(crAlpha) && pPixel->B == GetBValue(crAlpha))
							if (pPixel->R != GetRValue(crAlpha) || pPixel->G != GetGValue(crAlpha) || pPixel->B != GetBValue(crAlpha))
							//if (pPixel->A == 0)
								break;						

							x++;
							pPixel++;
							if (!Gdiplus::IsAlphaPixelFormat((Gdiplus::PixelFormat)pBkgrMaskBitmap->GetPixelFormat()))
								pPixel -= 1;
						}

						if (x < bitmapData.Width)
						{
							pPixel++;
							if (!Gdiplus::IsAlphaPixelFormat((Gdiplus::PixelFormat)pBkgrMaskBitmap->GetPixelFormat()))
								pPixel -= 1;
						}

						if (x > x0)
						{
							if (pData->rdh.nCount >= maxRects)
							{
								GlobalUnlock(hData);
								maxRects += ALLOC_UNIT;
								hData = GlobalReAlloc(hData, sizeof(RGNDATAHEADER) + (sizeof(RECT) * maxRects), GMEM_MOVEABLE);
								pData = (RGNDATA *)GlobalLock(hData);
							}

							RECT *pRc = (RECT *)&pData->Buffer;
							SetRect(&pRc[pData->rdh.nCount], x0, y, x, y + 1);
							if (x0 < pData->rdh.rcBound.left)
								pData->rdh.rcBound.left = x0;
							if (y < pData->rdh.rcBound.top)
								pData->rdh.rcBound.top = y;
							if (x > pData->rdh.rcBound.right)
								pData->rdh.rcBound.right = x;
							if (y + 1 > pData->rdh.rcBound.bottom)
								pData->rdh.rcBound.bottom = y + 1;
							pData->rdh.nCount++;

							if (pData->rdh.nCount == 500)
							{
								HRGN h = ExtCreateRegion(NULL, sizeof(RGNDATAHEADER) + (sizeof(RECT) * maxRects), pData);
								if (hRgn)
								{
									CombineRgn(hRgn, hRgn, h, RGN_OR);
									DeleteObject(h);
								}
								else
									hRgn = h;
								pData->rdh.nCount = 0;
								SetRect(&pData->rdh.rcBound, MAXLONG, MAXLONG, 0, 0);
							}
						}
					}

					pPixel += bitmapData.Stride - (bitmapData.Width * nBitsPixel);
				}

				HRGN h = ExtCreateRegion(NULL, sizeof(RGNDATAHEADER) + (sizeof(RECT) * maxRects), pData);
				if (hRgn)
				{
					CombineRgn(hRgn, hRgn, h, RGN_OR);
					DeleteObject(h);
				}
				else
					hRgn = h;
				pData->rdh.nCount = 0;
				GlobalUnlock(hData);
				GlobalFree(hData);
				SetRect(&pData->rdh.rcBound, MAXLONG, MAXLONG, 0, 0);
				pBkgrMaskBitmap->UnlockBits(&bitmapData);
			}
		}
	}

	::SetWindowRgn(m_hWnd, hRgn, TRUE);
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值