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

📄 effect.cpp

📁 一个国人自己实现图像库的程序(有参考价值)
💻 CPP
📖 第 1 页 / 共 4 页
字号:
#include "stdafx.h"
#include <math.h>
#include "..\..\Include\Pic\Effect.h"
#include "..\..\Include\fooBit.h"
#include "..\..\Include\C_x86_CPU.h"

//===================================================================
FCDibEffect::FCDibEffect (bool bUndo) : m_UndoFlag(bUndo) {
	m_UndoList.clear () ;
	m_RedoList.clear () ;
	m_hSelRgn = NULL ;
	::SetRectEmpty (&m_SelRect) ;
}
FCDibEffect::FCDibEffect (FCDibEffect & dib) : FCDib (* (FCDib *)&dib) {
	m_UndoList.clear () ;
	m_RedoList.clear () ;
	this->SetUndoEnable (dib.GetUndoFlag () ? true : false) ;
	m_hSelRgn = NULL ;
	::SetRectEmpty (&m_SelRect) ;
}
FCDibEffect::~FCDibEffect () {
	this->ClearAllList () ;
	this->ClearSelection () ;
}
void  FCDibEffect::operator= (const FCDibEffect & pic) {
	FCDib::operator = (*(FCDib *)&pic) ;
}
void  FCDibEffect::ClearAllList () {
	this->ClearRedoList () ;
	this->ClearUndoList () ;
}
void  FCDibEffect::ClearRedoList () {
	FCDib	* dib ;
	while (!m_RedoList.empty ())
	{
		dib = m_RedoList.front () ;
		m_RedoList.pop_front () ;
		delete dib ;
	}
}
void  FCDibEffect::AddToUndoList () {
	this->ClearRedoList () ;
	FCDib	* now = new FCDib ;
	*now = * (FCDib *) this ;
	m_UndoList.push_back (now) ;
}
void  FCDibEffect::ClearUndoList ()
{
	FCDib	* dib ;
	while (!m_UndoList.empty ())
	{
		dib = m_UndoList.back () ;
		m_UndoList.pop_back () ;
		delete dib ;
	}
}

//===================================================================
void  FCDibEffect::Undo ()
{
	if (m_UndoList.empty ())
		return ;

	FCDib	* now = new FCDib ;
	*now = * (FCDib *) this ; // 保存当前位图到Redo头
	m_RedoList.push_front (now) ;

	now = m_UndoList.back () ; // 取出Undo队列末尾的位图
	* (FCDib *) this = *now ;
	m_UndoList.pop_back () ;
	delete now ;
}
void  FCDibEffect::Redo ()
{
	if (m_RedoList.empty ())
		return ;

	FCDib *  now = new FCDib ;
	*now = * (FCDib *) this ; // 保存当前位图到Undo尾
	m_UndoList.push_back (now) ;

	now = m_RedoList.front () ; // 取出Redo队列开始的位图
	* (FCDib *) this = *now ;
	m_RedoList.pop_front () ;
	delete now ;
}
//===================================================================
void  FCDibEffect::Mirror ()
{
	if (this->ColorBits() < 8)
		return ;
	if (m_UndoFlag)
		this->AddToUndoList () ;

	if (m_hSelRgn == NULL) // 全图
		for (DWORD y = 0 ; y < this->Height() ; y++)
			switch (this->ColorBits())
			{
				case 8  : ::fooMemReverse ((BYTE*)this->GetBits (y), Width()) ; break ;
				case 16 : ::fooMemReverse ((WORD*)this->GetBits (y), Width()) ; break ;
				case 24 : ::fooMemReverse ((RGBTRIPLE*)this->GetBits (y), Width()) ; break ;
				case 32 : ::fooMemReverse ((DWORD*)this->GetBits (y), Width()) ; break ;
			}
	else
	{
		FCDibEffect		block ;
		this->GetSubBlock (&block, m_SelRect) ;
		block.Mirror () ;
		this->__BltBlock (block, m_SelRect.left, m_SelRect.top) ;
	}
}
//===================================================================
void  FCDibEffect::Stretch (DWORD dwWidth, DWORD dwHeight, int iType)
{
	if ((this->GetHandle() == NULL) || (dwWidth <= 0) || (dwHeight <=0))
		return ;

	FCDib		* Old = NULL ;
	if (m_UndoFlag) // 保存当前图象
	{
		this->AddToUndoList () ;
		Old = m_UndoList.back () ; // return FCDib *
	}	
	else
	{
		Old = new FCDib ;
		* Old = * (FCDib *) this ; // 保存当前图象
	}

	if (iType) // 成比例缩放
	{
		DWORD		dwOldW = Old->Width(), dwOldH = Old->Height() ;
		double		duOldScale = dwOldW / (double)dwOldH ;
		DWORD		dwTempW = (DWORD)(duOldScale * dwHeight) ;
		if (dwTempW < dwWidth) // 计算新的宽高
			dwWidth = dwTempW ;
		else
			dwHeight = (DWORD)(dwWidth / duOldScale) ;
	}

	if (this->Create (dwWidth, dwHeight, Old->ColorBits()))
	{
		HDC		hdcDesc = CreateCompatibleDC (NULL),
				hdcSrc  = CreateCompatibleDC (NULL) ;
		if (this->ColorBits() <= 8)
		{
			int			nNum = 1 << this->ColorBits() ;
			RGBQUAD		* prgb = (RGBQUAD *) new RGBQUAD[nNum] ;
			Old->GetColorTable (0, nNum, prgb) ;
			this->SetColorTable (0, nNum, prgb) ; // 复制调色板
			delete[] prgb ;
		}
		::SetStretchBltMode (hdcDesc, COLORONCOLOR) ;
		HBITMAP		hTa = (HBITMAP)SelectObject (hdcDesc, this->GetHandle ()) ;
		HBITMAP		hTb = (HBITMAP)SelectObject (hdcSrc, Old->GetHandle ()) ;
		::StretchBlt (hdcDesc, 0, 0, dwWidth, dwHeight,
					  hdcSrc, 0, 0, Old->Width(), Old->Height(), SRCCOPY) ;
		SelectObject (hdcDesc, hTa) ;
		SelectObject (hdcSrc, hTb) ;
		DeleteDC (hdcDesc) ;
		DeleteDC (hdcSrc) ;
	}
	if (!m_UndoFlag)
		delete Old ;
}
//===================================================================
void  FCDibEffect::__BltBlock (const FCDib & Dib, int x, int y)
{
	RECT	now = {0, 0, Width(), Height()} ,
			sub = {x, y, x+Dib.Width(), y+Dib.Height()} ,
			rcDest ;
	if ((::IntersectRect (&rcDest, &now, &sub) == 0) || (this->ColorBits() != Dib.ColorBits())
		|| (this->ColorBits() < 8))
		return ; // 没有相交区域

	HDC		hdcDesc = CreateCompatibleDC (NULL),
			hdcSrc  = CreateCompatibleDC (NULL) ;
	::SetStretchBltMode (hdcDesc, COLORONCOLOR) ;
	::SelectObject (hdcDesc, m_hSelRgn);
	HBITMAP		hTa = (HBITMAP)SelectObject (hdcDesc, this->GetHandle ()) ;
	HBITMAP		hTb = (HBITMAP)SelectObject (hdcSrc, Dib.GetHandle ()) ;
	::BitBlt (hdcDesc, x, y, rcDest.right - rcDest.left, rcDest.bottom - rcDest.top,
			  hdcSrc, 0, 0, SRCCOPY) ;
	SelectObject (hdcDesc, hTa) ;
	SelectObject (hdcSrc, hTb) ;
	SelectClipRgn (hdcSrc, NULL) ;
	DeleteDC (hdcDesc) ;
	DeleteDC (hdcSrc) ;
}
//===================================================================
void  FCDibEffect::AdjustBrightness (int iPercent, BOOL bFlag)
{
	if (this->ColorBits() == 16)
		return ;
	if (m_UndoFlag)
		this->AddToUndoList () ;

	if (m_hSelRgn == NULL) // 整图
	{
		int		nSpan = this->ColorBits() / 8 ;
		if (!bFlag)
			iPercent = 128 * iPercent / 100 ; // 转换成x/128
		if (this->ColorBits() > 8)
			for (int y=0 ; y < Height() ; y++)
			{
				BYTE	* pPixel = this->GetBits (y) ;
				if (bFlag)	// 按增量
					::fooMMX_ADD ((BYTE *)pPixel, nSpan * Width(), iPercent) ;
				else	// 按百分比
					for (DWORD i = 0 ; i < Width() ; i++, pPixel += nSpan)
					{
						pPixel[0] = min (pPixel[0] * iPercent / 128, 255) ;
						pPixel[1] = min (pPixel[1] * iPercent / 128, 255) ;
						pPixel[2] = min (pPixel[2] * iPercent / 128, 255) ;
					}
			}
		else // 调色板图象
		{
			UINT		nNum = 1 << this->ColorBits() ;
			RGBQUAD		* pPalette = new RGBQUAD [nNum] ;
			this->GetColorTable (0, nNum, pPalette) ;
			if (bFlag)	// 按增量
				::fooMMX_ADD ((BYTE *)pPalette, 4 * nNum, iPercent) ;
			else	// 按百分比
				for (int i = 0 ; i < nNum ; i++)
				{
					pPalette[i].rgbBlue = min (pPalette[i].rgbBlue * iPercent / 128, 255) ;
					pPalette[i].rgbGreen = min (pPalette[i].rgbGreen * iPercent / 128, 255) ;
					pPalette[i].rgbRed = min (pPalette[i].rgbRed * iPercent / 128, 255) ;
				}
			this->SetColorTable (0, nNum, pPalette) ;
			delete[] pPalette ;
		}
	}
	else
	{
		FCDibEffect		block ;
		this->GetSubBlock (&block, m_SelRect) ;
		block.AdjustBrightness (iPercent, bFlag) ;
		this->__BltBlock (block, m_SelRect.left, m_SelRect.top) ;
	}
}
//===================================================================
void  FCDibEffect::AdjustContrast (int iPercent)
{
	if (this->ColorBits() == 16)
		return ;
	if (m_UndoFlag)
		this->AddToUndoList () ;

	if (m_hSelRgn == NULL) // 整图
	{
		int		nSpan = this->ColorBits() / 8 ;
		iPercent = 128 * iPercent / 100 ; // 转换成x/128
		if (this->ColorBits() > 8)
			for (int y=0 ; y < Height() ; y++)
			{
				BYTE	* pPixel = this->GetBits (y) ;
				for (DWORD i = 0 ; i < Width() ; i++, pPixel += nSpan)
				{
					pPixel[0] = max (min (128 + (pPixel[0] - 128) * iPercent / 128, 255), 0) ;
					pPixel[1] = max (min (128 + (pPixel[1] - 128) * iPercent / 128, 255), 0) ;
					pPixel[2] = max (min (128 + (pPixel[2] - 128) * iPercent / 128, 255), 0) ;
				}
			}
		else // 调色板图象
		{
			UINT		nNum = 1 << this->ColorBits() ;
			RGBQUAD		* pPalette = new RGBQUAD [nNum] ;
			this->GetColorTable (0, nNum, pPalette) ;
			for (int i = 0 ; i < nNum ; i++)
			{
				pPalette[i].rgbBlue = max (min (128 + (pPalette[i].rgbBlue - 128) * iPercent / 128, 255), 0) ;
				pPalette[i].rgbGreen = max (min (128 + (pPalette[i].rgbGreen - 128) * iPercent / 128, 255), 0) ;
				pPalette[i].rgbRed = max (min (128 + (pPalette[i].rgbRed - 128) * iPercent / 128, 255), 0) ;
			}
			this->SetColorTable (0, nNum, pPalette) ;
			delete[] pPalette ;
		}
	}
	else
	{
		FCDibEffect		block ;
		this->GetSubBlock (&block, m_SelRect) ;
		block.AdjustContrast (iPercent) ;
		this->__BltBlock (block, m_SelRect.left, m_SelRect.top) ;
	}
}
//===================================================================
void  FCDibEffect::AdjustHS (int iPercentHue, int iPercentSat)
{
	if (this->ColorBits() == 16)
		return ;
	if (m_UndoFlag)
		this->AddToUndoList () ;

	if (m_hSelRgn == NULL) // 整图
	{
		iPercentHue = 128 * iPercentHue / 100 ; // 转换成x/128
		iPercentSat = 128 * iPercentSat / 100 ; // 转换成x/128
		int			nSpan = this->ColorBits() / 8 ;
		double		H, L, S ;
		if (this->ColorBits() > 8)
			for (int y=0 ; y < Height() ; y++)
			{
				BYTE	* pPixel = this->GetBits (y) ;
				for (DWORD i = 0 ; i < Width() ; i++, pPixel += nSpan)
				{
					FCDib::fooRGBtoHLS (*(RGBTRIPLE *)pPixel, &H, &L, &S);
					if (iPercentHue != 128)
						H = H * iPercentHue / 128 ;
					if (iPercentSat != 128)
						S = S * iPercentSat / 128 ;
					* (RGBTRIPLE *) pPixel = FCDib::fooHLStoRGB (H, L, S) ;
				}
			}
		else // 调色板图象
		{
			UINT		nNum = 1 << this->ColorBits() ;
			RGBQUAD		* pPalette = new RGBQUAD [nNum] ;
			this->GetColorTable (0, nNum, pPalette) ;
			for (int i = 0 ; i < nNum ; i++)
			{
				FCDib::fooRGBtoHLS (*(RGBTRIPLE *)&pPalette[i], &H, &L, &S);
				if (iPercentHue != 128)
					H = H * iPercentHue / 128 ;
				if (iPercentSat != 128)
					S = S * iPercentSat / 128 ;
				*(RGBTRIPLE *)&pPalette[i] = FCDib::fooHLStoRGB (H, L, S) ;
			}
			this->SetColorTable (0, nNum, pPalette) ;
			delete[] pPalette ;
		}
	}
	else
	{
		FCDibEffect		block ;
		this->GetSubBlock (&block, m_SelRect) ;
		block.AdjustHS (iPercentHue, iPercentSat) ;
		this->__BltBlock (block, m_SelRect.left, m_SelRect.top) ;
	}
}
//===================================================================
void  FCDibEffect::AdjustRGB (int iValueR, int iValueG, int iValueB)
{
	if (this->ColorBits() == 16)
		return ;
	if (m_UndoFlag)
		this->AddToUndoList () ;

	if (m_hSelRgn == NULL) // 整图
	{
		int		nSpan = this->ColorBits() / 8 ; // 每象素字节数3, 4
		if (this->ColorBits() > 8)
			for (int y=0 ; y < Height() ; y++)
			{
				BYTE	* pPixel = this->GetBits (y) ;
				for (int x=0 ; x < Width() ; x++, pPixel += nSpan)
				{
					if (iValueB != 0)
						pPixel[0] = max (min (pPixel[0] + iValueB, 255), 0) ;
					if (iValueG != 0)
						pPixel[1] = max (min (pPixel[1] + iValueG, 255), 0) ;
					if (iValueR != 0)
						pPixel[2] = max (min (pPixel[2] + iValueR, 255), 0) ;
				}
			}
		else // 调色板图象
		{
			UINT		nNum = 1 << this->ColorBits() ;
			RGBQUAD		* pPalette = new RGBQUAD [nNum] ;
			this->GetColorTable (0, nNum, pPalette) ;
			for (int i=0 ; i < nNum ; i++)
			{
				if (iValueB != 0)
					pPalette[i].rgbBlue = max (min (pPalette[i].rgbBlue + iValueB, 255), 0) ;
				if (iValueG != 0)
					pPalette[i].rgbGreen = max (min (pPalette[i].rgbGreen + iValueG, 255), 0) ;
				if (iValueR != 0)
					pPalette[i].rgbRed = max (min (pPalette[i].rgbRed + iValueR, 255), 0) ;
			}
			this->SetColorTable (0, nNum, pPalette) ;
			delete[] pPalette ;

⌨️ 快捷键说明

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