⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 enbitmap.cpp

📁 最新visualC++编程200例书籍源码包括对数据库的操作
💻 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 <afxpriv.h>

#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);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -