www.pudn.com > WBDraw.rar > EnBitmap.cpp


// EnBitmap.cpp: implementation of the CEnBitmap class (c) daniel godson 2002. 
// 
//  
//  Cryingwind 
//    
//  
////////////////////////////////////////////////////////////////////// 
#include "stdafx.h" 
#include "EnBitmap.h" 
#include "color.h" 
 
#include "resource.h" 
 
#include  
 
#ifdef _DEBUG 
#undef THIS_FILE 
static char THIS_FILE[]=__FILE__; 
#define new DEBUG_NEW 
#endif 
 
/////////////////////////////////////////////////////////////////////// 
LPRECT C32BitImageProcessor::btnpos=0; 
UINT ID_BK; 
 
C32BitImageProcessor::C32BitImageProcessor(BOOL bEnableWeighting) : m_bWeightingEnabled(bEnableWeighting) 
{ 
	m_bBk = FALSE; 
	bk=new CEnBitmap; 
	bk->LoadBitmap(ID_BK); 
	bkrgbx=bk->GetDIBits32(); 
	BITMAP BM; 
	bk->GetBitmap(&BM); 
	bk->bksize=CSize(BM.bmWidth,BM.bmHeight); 
} 
 
void C32BitImageProcessor::SetBkColor(int R, int G, int B) 
{ 
	m_bBk = TRUE; 
	m_nRed = R; 
	m_nGreen = G; 
	m_nBlue = B; 
} 
 
C32BitImageProcessor::~C32BitImageProcessor() 
{ 
} 
 
CSize C32BitImageProcessor::CalcDestSize(CSize sizeSrc)  
{  
	return sizeSrc; // default 
} 
 
BOOL C32BitImageProcessor::IsBkColor(RGBX*p) 
{ 
	if (!m_bBk) 
		return FALSE; 
	if (p->btRed == m_nRed && p->btGreen == m_nGreen && p->btBlue==m_nBlue) 
		return TRUE; 
	return FALSE; 
} 
 
BOOL C32BitImageProcessor::ProcessPixels(RGBX* pSrcPixels, CSize , RGBX* pDestPixels, CSize sizeDest) 
{  
	CopyMemory(pDestPixels, pSrcPixels, sizeDest.cx * 4 * sizeDest.cy); // default 
	return TRUE; 
} 
  
// C32BitImageProcessor::CalcWeightedColor(...) is inlined in EnBitmap.h 
 
////////////////////////////////////////////////////////////////////// 
// Construction/Destruction 
////////////////////////////////////////////////////////////////////// 
 
CEnBitmap::CEnBitmap(COLORREF crBkgnd) : m_crBkgnd(crBkgnd) 
{ 
 
} 
 
CEnBitmap::~CEnBitmap() 
{ 
 
} 
 
BOOL CEnBitmap::GrayImage() 
{ 
	CImageGrayer gr;	 
	return ProcessImage(&gr); 
} 
 
 
BOOL CEnBitmap::ProcessImage(C32BitImageProcessor* pProcessor) 
{ 
	C32BIPArray aProcessors; 
 
	aProcessors.Add(pProcessor); 
 
	return ProcessImage(aProcessors); 
} 
 
BOOL CEnBitmap::ProcessImage(C32BIPArray& aProcessors) 
{ 
	ASSERT (GetSafeHandle()); 
 
	if (!GetSafeHandle()) 
		return FALSE; 
 
	if (!aProcessors.GetSize()) 
		return TRUE; 
 
	int nProcessor, nCount = aProcessors.GetSize(); 
 
	// retrieve src and final dest sizes 
	BITMAP BM; 
 
	if (!GetBitmap(&BM)) 
		return FALSE; 
 
	CSize sizeSrc(BM.bmWidth, BM.bmHeight); 
	CSize sizeDest(sizeSrc), sizeMax(sizeSrc); 
 
	for (nProcessor = 0; nProcessor < nCount; nProcessor++) 
	{ 
		sizeDest = aProcessors[nProcessor]->CalcDestSize(sizeDest); 
		sizeMax = CSize(max(sizeMax.cx, sizeDest.cx), max(sizeMax.cy, sizeDest.cy)); 
	} 
 
	// prepare src and dest bits 
	RGBX* pSrcPixels = GetDIBits32(); 
 
	if (!pSrcPixels) 
		return FALSE; 
 
	RGBX* pDestPixels = new RGBX[sizeMax.cx * sizeMax.cy]; 
 
	if (!pDestPixels) 
		return FALSE; 
 
	Fill(pDestPixels, sizeMax, m_crBkgnd); 
 
	BOOL bRes = TRUE; 
	sizeDest = sizeSrc; 
 
	// do the processing 
	for (nProcessor = 0; bRes && nProcessor < nCount; nProcessor++) 
	{ 
		// if its the second processor or later then we need to copy 
		// the previous dest bits back into source. 
		// we also need to check that sizeSrc is big enough 
		if (nProcessor > 0) 
		{ 
			if (sizeSrc.cx < sizeDest.cx || sizeSrc.cy < sizeDest.cy) 
			{ 
				delete [] pSrcPixels; 
				pSrcPixels = new RGBX[sizeDest.cx * sizeDest.cy]; 
			} 
 
			CopyMemory(pSrcPixels, pDestPixels, sizeDest.cx * 4 * sizeDest.cy); // default 
			Fill(pDestPixels, sizeDest, m_crBkgnd); 
		} 
 
		sizeSrc = sizeDest; 
		sizeDest = aProcessors[nProcessor]->CalcDestSize(sizeSrc); 
		 
		bRes = aProcessors[nProcessor]->ProcessPixels(pSrcPixels, sizeSrc, pDestPixels, sizeDest); 
	} 
 
	// update the bitmap 
	if (bRes) 
	{ 
		// set the bits 
		HDC hdc = GetDC(NULL); 
		HBITMAP hbmSrc = ::CreateCompatibleBitmap(hdc, sizeDest.cx, sizeDest.cy); 
 
		if (hbmSrc) 
		{ 
			BITMAPINFO bi; 
 
			if (PrepareBitmapInfo32(bi, hbmSrc)) 
			{ 
				if (SetDIBits(hdc, hbmSrc, 0, sizeDest.cy, pDestPixels, &bi, DIB_RGB_COLORS)) 
				{ 
					// delete the bitmap and attach new 
					DeleteObject(); 
					bRes = Attach(hbmSrc); 
				} 
			} 
 
			::ReleaseDC(NULL, hdc); 
 
			if (!bRes) 
				::DeleteObject(hbmSrc); 
		} 
	} 
 
	delete [] pSrcPixels; 
	delete [] pDestPixels; 
 
	return bRes; 
} 
 
RGBX* CEnBitmap::GetDIBits32() 
{ 
	BITMAPINFO bi; 
 
	int nHeight = PrepareBitmapInfo32(bi); 
	 
	if (!nHeight) 
		return FALSE; 
 
	BYTE* pBits = (BYTE*)new BYTE[bi.bmiHeader.biSizeImage]; 
	HDC hdc = GetDC(NULL); 
 
	if (!GetDIBits(hdc, (HBITMAP)GetSafeHandle(), 0, nHeight, pBits, &bi, DIB_RGB_COLORS)) 
	{ 
		delete pBits; 
		pBits = NULL; 
	} 
 
	::ReleaseDC(NULL, hdc); 
 
	return (RGBX*)pBits; 
} 
 
BOOL CEnBitmap::PrepareBitmapInfo32(BITMAPINFO& bi, HBITMAP hBitmap) 
{ 
	if (!hBitmap) 
		hBitmap = (HBITMAP)GetSafeHandle(); 
 
	BITMAP BM; 
 
	if (!::GetObject(hBitmap, sizeof(BM), &BM)) 
		return FALSE; 
 
	bi.bmiHeader.biSize = sizeof(bi.bmiHeader); 
	bi.bmiHeader.biWidth = BM.bmWidth; 
	bi.bmiHeader.biHeight = -BM.bmHeight; 
	bi.bmiHeader.biPlanes = 1; 
	bi.bmiHeader.biBitCount = 32; // 32 bit 
	bi.bmiHeader.biCompression = BI_RGB; // 32 bit 
	bi.bmiHeader.biSizeImage = BM.bmWidth * 4 * BM.bmHeight; // 32 bit 
	bi.bmiHeader.biClrUsed = 0; 
	bi.bmiHeader.biClrImportant = 0; 
 
	return BM.bmHeight; 
} 
 
BOOL CEnBitmap::Fill(RGBX* pPixels, CSize size, COLORREF color) 
{ 
	if (!pPixels) 
		return FALSE; 
 
	if (color == -1 || color == RGB(255, 255, 255)) 
		FillMemory(pPixels, size.cx * 4 * size.cy, 255); // white 
 
	else if (color == 0) 
		FillMemory(pPixels, size.cx * 4 * size.cy, 0); // black 
 
	else 
	{ 
		// fill the first line with the color 
		RGBX* pLine = &pPixels[0]; 
		int nSize = 1; 
 
		pLine[0] = RGBX(color); 
 
		while (1) 
		{ 
			if (nSize > size.cx) 
				break; 
 
			// else 
			int nAmount = min(size.cx - nSize, nSize) * 4; 
 
			CopyMemory(&pLine[nSize], pLine, nAmount); 
			nSize *= 2; 
		} 
 
		// use that line to fill the rest of the block 
		int nRow = 1; 
 
		while (1) 
		{ 
			if (nRow > size.cy) 
				break; 
 
			// else 
			int nAmount = min(size.cy - nRow, nRow) * size.cx * 4; 
 
			CopyMemory(&pPixels[nRow * size.cx], pPixels, nAmount); 
			nRow *= 2; 
		} 
	} 
 
	return TRUE; 
} 
BOOL CEnBitmap::MakeDisabled(COLORREF bk) 
{ 
	int R = GetRValue(bk); 
	int G = GetGValue(bk); 
	int B = GetBValue(bk); 
 
	CImageHigh high(0.08f); 
	high.SetBkColor(R, G, B); 
	CImageGrayer gray; 
	gray.SetBkColor(R, G, B); 
 
	C32BIPArray aProcessors; 
	aProcessors.Add(&gray); 
 
	return ProcessImage(aProcessors); 
} 
 
BOOL CEnBitmap::MakeNormal(COLORREF bk) 
{ 
	int R = GetRValue(bk); 
	int G = GetGValue(bk); 
	int B = GetBValue(bk); 
 
	C32BIPArray aProcessors; 
	CImageNormal normal; 
	normal.SetBkColor(R, G, B); 
	aProcessors.Add(&normal); 
	return ProcessImage(aProcessors); 
						 
	return TRUE; 
} 
 
BOOL CEnBitmap::MakeNotActive(COLORREF bk) 
{ 
	int R = GetRValue(bk); 
	int G = GetGValue(bk); 
	int B = GetBValue(bk); 
 
	C32BIPArray aProcessors; 
 
	CImageHigh high2(0.04f); 
	high2.SetBkColor(R, G, B); 
	aProcessors.Add(&high2); 
	return ProcessImage(aProcessors); 
} 
 
 
BOOL CImageGrayer::ProcessPixels(RGBX* pSrcPixels, CSize sizeSrc, RGBX* pDestPixels, CSize ) 
{ 
	int x,y; 
	for (int nX = 0; nX < sizeSrc.cx; nX++) 
	{ 
		for (int nY = 0; nY < sizeSrc.cy; nY++) 
		{ 
			RGBX* pRGBSrc = &pSrcPixels[nY * sizeSrc.cx + nX]; 
			RGBX* pRGBDest = &pDestPixels[nY * sizeSrc.cx + nX]; 
			if (IsBkColor(pRGBSrc)) 
			{ 
				//---------- 
				x=btnpos[nX/24].left+nX%24; 
				y=btnpos[nX/24].top +nY; 
				RGBX* bkSrc=&bkrgbx[y*bk->bksize.cx  +nX]; 
				*pRGBDest = * bkSrc; 
				//---------- 
			} 
			else 
			{ 
 
				*pRGBDest = pRGBSrc->Gray(); 
			} 
		} 
	} 
 
	return TRUE; 
} 
 
BOOL CImageNormal::ProcessPixels(RGBX* pSrcPixels, CSize sizeSrc, RGBX* pDestPixels, CSize ) 
{ 
	int x,y; 
	for (int nX = 0; nX < sizeSrc.cx; nX++) 
	{ 
		for (int nY = 0; nY < sizeSrc.cy; nY++) 
		{ 
			RGBX* pRGBSrc = &pSrcPixels[nY * sizeSrc.cx + nX]; 
			RGBX* pRGBDest = &pDestPixels[nY * sizeSrc.cx + nX]; 
			if (IsBkColor(pRGBSrc)) 
			{ 
				//---------- 
				x=btnpos[nX/24].left+nX%24; 
				y=btnpos[nX/24].top +nY; 
				RGBX* bkSrc=&bkrgbx[y*bk->bksize.cx  +nX]; 
				*pRGBDest = * bkSrc; 
				//---------- 
			} 
			else 
			{ 
 
				*pRGBDest = *pRGBSrc; 
			} 
		} 
	} 
 
	return TRUE; 
} 
 
CImageHigh::CImageHigh(float nL) 
{ 
	m_fLumDecr = nL; 
} 
 
BOOL CImageHigh::ProcessPixels(RGBX* pSrcPixels, CSize sizeSrc, RGBX* pDestPixels, CSize ) 
{ 
	CColor cnv; 
	int x,y; 
	for (int nX = 0; nX < sizeSrc.cx; nX++) 
	{ 
		for (int nY = 0; nY < sizeSrc.cy; nY++) 
		{ 
			RGBX* pRGBSrc = &pSrcPixels[nY * sizeSrc.cx + nX]; 
			RGBX* pRGBDest = &pDestPixels[nY * sizeSrc.cx + nX]; 
			if (IsBkColor(pRGBSrc)) 
			{ 
				//---------- 
				x=btnpos[nX/24].left+nX%24; 
				y=btnpos[nX/24].top +nY; 
				RGBX* bkSrc=&bkrgbx[y*bk->bksize.cx  +nX]; 
				*pRGBDest = * bkSrc; 
				//---------- 
			} 
			else//这里有反色的作用 
			{ 
				cnv.SetRGB(pRGBSrc->btRed, pRGBSrc->btGreen, pRGBSrc->btBlue); 
				float L = cnv.GetLuminance(); 
 
				if (m_fLumDecr>0 && L<1.0) 
				{ 
					L = min(1, L+m_fLumDecr); 
					cnv.SetLuminance(L); 
				} 
				else if (m_fLumDecr<0 && L>0) 
				{ 
					L = max(0, L+m_fLumDecr); 
					cnv.SetLuminance(L); 
				} 
			 
				pRGBDest->btRed = (BYTE)cnv.GetRed(); 
				pRGBDest->btBlue= (BYTE)cnv.GetBlue(); 
				pRGBDest->btGreen = (BYTE)cnv.GetGreen(); 
			} 
		} 
	} 
 
	return TRUE; 
} 
 
void	CToolBar24::SetFullColorImage(UINT ID, COLORREF rgbBack, LPRECT lprect, int num) 
{ 
 
	//---------- 
	if(lprect!=NULL) 
	{ 
		C32BitImageProcessor::btnpos=new RECT[num]; 
		memcpy(C32BitImageProcessor::btnpos,lprect,num*sizeof(RECT)); 
	} 
	else 
	{ 
		m_bmToolbar.DeleteObject(); 
		m_imgToolbar.DeleteImageList(); 
		m_bmToolbarDis.DeleteObject(); 
		m_imgToolbarDis.DeleteImageList(); 
		m_bmToolbarNA.DeleteObject(); 
		m_imgToolbarNA.DeleteImageList(); 
	} 
	//---------- 
 
	m_bmToolbar.LoadBitmap(ID); 
	m_bmToolbar.MakeNormal(RGB(255, 0, 255)); 
	m_imgToolbar.Create(24, 24, ILC_COLOR24|ILC_MASK, 1, 1); 
	m_imgToolbar.Add(&m_bmToolbar, rgbBack); 
	GetToolBarCtrl().SetImageList(&m_imgToolbar); 
 
	m_bmToolbarDis.LoadBitmap(ID); 
	m_bmToolbarDis.MakeDisabled(RGB(255, 0, 255)); 
	m_imgToolbarDis.Create(24, 24, ILC_COLOR24|ILC_MASK, 1, 1); 
	m_imgToolbarDis.Add(&m_bmToolbarDis, rgbBack); 
	GetToolBarCtrl().SetDisabledImageList(&m_imgToolbarDis); 
 
	m_bmToolbarNA.LoadBitmap(ID); 
	m_bmToolbarNA.MakeNotActive(RGB(255, 0, 255)); 
	m_imgToolbarNA.Create(24, 24, ILC_COLOR24|ILC_MASK, 1, 1); 
	m_imgToolbarNA.Add(&m_bmToolbarNA, rgbBack); 
	GetToolBarCtrl().SetHotImageList(&m_imgToolbarNA); 
} 
 
BEGIN_MESSAGE_MAP(CToolBar24, CToolBar) 
	//{{AFX_MSG_MAP(CBmpToolBar) 
	ON_WM_ERASEBKGND() 
	//}}AFX_MSG_MAP 
END_MESSAGE_MAP() 
 
void CToolBar24::UpdateBk(UINT ID, COLORREF rgbBack, UINT newbk) 
{ 
	ID_BK=newbk; 
	CBitmap tmp; 
	tmp.LoadBitmap(ID_BK); 
	brush.DeleteObject( ); 
	brush.CreatePatternBrush(&tmp); 
	SetFullColorImage(ID,rgbBack,NULL,NULL); 
	Invalidate(); 
} 
 
BOOL CToolBar24::OnEraseBkgnd(CDC* pDC)  
{ 
	// TODO: Add your message handler code here and/or call default 
 
	RECT rect; 
	GetWindowRect(&rect); 
	ScreenToClient(&rect); 
	pDC->FillRect(&rect,&brush); 
 
	return TRUE;	 
} 
 
CToolBar24::CToolBar24() 
{ 
	ID_BK=IDB_BITMAP2; 
	CBitmap tmp; 
	tmp.LoadBitmap(ID_BK); 
	brush.CreatePatternBrush(&tmp); 
}