Click here to Skip to main content
15,890,185 members
Articles / Desktop Programming / MFC
Tip/Trick

Replace one color with another in the bitmap of a given device context

Rate me:
Please Sign up or sign in to vote.
4.80/5 (2 votes)
6 Feb 2012CPOL 14.8K  
Given a device context, replace a color (clrColorReplace) in a rectangular region of the device context with another color (clrColorFill)
This API would simply replace one color with another in a rectangular region
of a given device context:

void ReplaceColor(HDC hDC, CRect rcReplaceArea, COLORREF clrColorReplace, COLORREF clrColorFill)
{
	CDC* pDC = CDC::FromHandle(hDC);

	CPoint pt = rcReplaceArea.TopLeft();
	
	CDC memDCMonoChrome;
	memDCMonoChrome.CreateCompatibleDC(pDC);
	CBitmap bmpMonoChrome;
	bmpMonoChrome.CreateCompatibleBitmap(&memDCMonoChrome, rcReplaceArea.Width(), rcReplaceArea.Height());
	CBitmap* pOldMonoBitmap = memDCMonoChrome.SelectObject(&bmpMonoChrome);
	
	COLORREF nOldBkColor = pDC->SetBkColor(clrColorReplace);
	// BLT to mono dc so that mask color will have 1 set and the other colors 0
	memDCMonoChrome.BitBlt(0, 0, rcReplaceArea.Width(), rcReplaceArea.Height(), pDC, pt.x, pt.y, SRCCOPY);

	CDC memDC;
	memDC.CreateCompatibleDC(pDC);
	CBitmap bmp;
	bmp.CreateCompatibleBitmap(pDC, rcReplaceArea.Width(), rcReplaceArea.Height());
	CBitmap* pOldBitmap = memDC.SelectObject(&bmp);

	COLORREF nOldMemDCBkColor = memDC.SetBkColor(clrColorFill);
	COLORREF nOldMemDCTextColor = memDC.SetTextColor(RGB(255, 255, 255));
	// BLT to memory DC so that the monochrome white is set to fill color and the monochrome black is set to white
	memDC.BitBlt(0, 0, rcReplaceArea.Width(), rcReplaceArea.Height(), &memDCMonoChrome, 0, 0, SRCCOPY);

	// AND pDC with memory dc so that the replace color part is blackened out and all other colors remains same
	pDC->BitBlt(pt.x, pt.y, rcReplaceArea.Width(), rcReplaceArea.Height(), &memDC, 0, 0, SRCAND);

	memDC.SetTextColor(RGB(0, 0, 0));	
	// BLT to memory DC so that the monochrome white is set to fill color and the monochrome black is set to black
	memDC.BitBlt(0, 0, rcReplaceArea.Width(), rcReplaceArea.Height(), &memDCMonoChrome, 0, 0, SRCCOPY);

	// OR pDC with memory dc so that all colors remains as they where except the blackened out (replace color) 
	// part receives the fill color 
	pDC->BitBlt(pt.x, pt.y, rcReplaceArea.Width(), rcReplaceArea.Height(), &memDC, 0, 0, SRCPAINT);

	// Set the original values back
	memDC.SetTextColor(nOldMemDCTextColor);
	memDC.SetBkColor(nOldMemDCBkColor);
	
	pDC->SetBkColor(nOldBkColor);

	// Set the original bitmaps back
	memDCMonoChrome.SelectObject(pOldMonoBitmap);
	memDC.SelectObject(pOldBitmap);
}

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Technical Lead Kotha Technologies
Bangladesh Bangladesh
If you are not in - you are out !
- Chapter 1

Comments and Discussions

 
-- There are no messages in this forum --