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

📄 gradient.cpp

📁 很好的东西!是初学者比较需要的东西。一个比较使用的程序。希望大家能用到
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// Gradient.cpp: implementation of the CGradient class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "Gradient.h"
#include "math.h"


CGradient::CGradient()
{
}

CGradient::~CGradient()
{
}

void CGradient::HorizontalGradient(HDC hDC, LPRECT lpRect, COLORREF sColor, COLORREF eColor, BOOL bGamma, double gamma)
{
	// Gradient params
	int width = lpRect->right - lpRect->left - 1;
	int height = lpRect->bottom - lpRect->top - 1;

	// Draw gradient
	HBRUSH hBrush = NULL;
	double percent;
	unsigned char red, green, blue;
	COLORREF color;
	RECT rect;
	for (int i=0; i<width-1; i++)
	{
		// Gradient color percent
		percent = 1 - (double)i / (double)(width-2);

		// Gradient color
		red = (unsigned char)(GetRValue(sColor)*percent) + (unsigned char)(GetRValue(eColor)*(1-percent));
		green = (unsigned char)(GetGValue(sColor)*percent) + (unsigned char)(GetGValue(eColor)*(1-percent));
		blue = (unsigned char)(GetBValue(sColor)*percent) + (unsigned char)(GetBValue(eColor)*(1-percent));
		if (bGamma)
		{
			red = (unsigned char)(pow((double)red/255.0, gamma) * 255);
			green = (unsigned char)(pow((double)green/255.0, gamma) * 255);
			blue = (unsigned char)(pow((double)blue/255.0, gamma) * 255);
		}
		color = RGB(red, green, blue);

		// Gradient
		rect.left = lpRect->left + i + 1;
		rect.top = lpRect->top + 1;
		rect.right = rect.left + 1;
		rect.bottom = lpRect->bottom - 1;
		hBrush = CreateSolidBrush(color);
		FillRect(hDC, &rect, hBrush);
		DeleteObject(hBrush);
	}
}

void CGradient::VerticalGradient(HDC hDC, LPRECT lpRect, COLORREF sColor, COLORREF eColor, BOOL bGamma, double gamma)
{
	// Gradient params
	int width = lpRect->right - lpRect->left - 1;
	int height = lpRect->bottom - lpRect->top - 1;

	// Draw gradient
	HBRUSH hBrush = NULL;
	double percent;
	unsigned char red, green, blue;
	COLORREF color;
	RECT rect;
	for (int i=0; i<height-1; i++)
	{
		// Gradient color percent
		percent = 1 - (double)i / (double)(height-2);

		// Gradient color
		red = (unsigned char)(GetRValue(sColor)*percent) + (unsigned char)(GetRValue(eColor)*(1-percent));
		green = (unsigned char)(GetGValue(sColor)*percent) + (unsigned char)(GetGValue(eColor)*(1-percent));
		blue = (unsigned char)(GetBValue(sColor)*percent) + (unsigned char)(GetBValue(eColor)*(1-percent));
		if (bGamma)
		{
			red = (unsigned char)(pow((double)red/255.0, gamma) * 255);
			green = (unsigned char)(pow((double)green/255.0, gamma) * 255);
			blue = (unsigned char)(pow((double)blue/255.0, gamma) * 255);
		}
		color = RGB(red, green, blue);

		// Gradient
		rect.left = lpRect->left + 1;
		rect.top = lpRect->top + i + 1;
		rect.right = lpRect->right - 1;
		rect.bottom = rect.top + 1;
		hBrush = CreateSolidBrush(color);
		FillRect(hDC, &rect, hBrush);
		DeleteObject(hBrush);
	}
}

void CGradient::ForwardDiagonalGradient(HDC hDC, LPRECT lpRect, COLORREF sColor, COLORREF eColor, BOOL bGamma, double gamma)
{
	// Gradient params
	int width = lpRect->right - lpRect->left - 1;
	int height = lpRect->bottom - lpRect->top - 1;
	double angle = (double)height / (double)width;

	// Draw gradient
	HPEN hPen = NULL;
	HPEN hOldPen = NULL;
	double percent;
	unsigned char sRed, sGreen, sBlue, eRed, eGreen, eBlue;
	COLORREF colorStart, colorEnd;
	int offsetLeft = lpRect->top + 1;
	int offsetRight = lpRect->bottom - 1;
	int offsetTop = lpRect->left + 1;
	int offsetBottom = lpRect->bottom - 1;
	POINT pointStart, pointEnd;
	POINT sPoint, ePoint;
	int i, j;
	for (i=0; i<=width; i++)
	{
		// Gradient color percent
		percent = 1 - (double)i/(double)(2*width);

		// Start color
		sRed = (unsigned char)(GetRValue(sColor)*percent) + (unsigned char)(GetRValue(eColor)*(1-percent));
		sGreen = (unsigned char)(GetGValue(sColor)*percent) + (unsigned char)(GetGValue(eColor)*(1-percent));
		sBlue = (unsigned char)(GetBValue(sColor)*percent) + (unsigned char)(GetBValue(eColor)*(1-percent));
		if (bGamma)
		{
			sRed = (unsigned char)(pow((double)sRed/255.0, gamma) * 255);
			sGreen = (unsigned char)(pow((double)sGreen/255.0, gamma) * 255);
			sBlue = (unsigned char)(pow((double)sBlue/255.0, gamma) * 255);
		}
		colorStart = RGB(sRed, sGreen, sBlue);

		// End color
		eRed = (unsigned char)(GetRValue(eColor)*percent) + (unsigned char)(GetRValue(sColor)*(1-percent));
		eGreen = (unsigned char)(GetGValue(eColor)*percent) + (unsigned char)(GetGValue(sColor)*(1-percent));
		eBlue = (unsigned char)(GetBValue(eColor)*percent) + (unsigned char)(GetBValue(sColor)*(1-percent));
		if (bGamma)
		{
			eRed = (unsigned char)(pow((double)eRed/255.0, gamma) * 255);
			eGreen = (unsigned char)(pow((double)eGreen/255.0, gamma) * 255);
			eBlue = (unsigned char)(pow((double)eBlue/255.0, gamma) * 255);
		}
		colorEnd = RGB(eRed, eGreen, eBlue);

		// Start and end points on the left side
		pointStart.x = lpRect->left + 1;
		pointStart.y = lpRect->top+(int)(angle*i) + 1;
		if (pointStart.y > lpRect->bottom-2)
			pointStart.y = lpRect->bottom-2;
		pointEnd.x = lpRect->left+i+1;
		if (pointEnd.x > lpRect->right-2)
			pointEnd.x = lpRect->right-2;
		pointEnd.y = lpRect->top + 1;

		// Left side
		hPen = CreatePen(PS_SOLID, 1, colorStart);
		hOldPen = (HPEN)SelectObject(hDC, hPen);
		MoveToEx(hDC, pointStart.x, pointStart.y, NULL);
		LineTo(hDC, pointEnd.x, pointEnd.y);
		// Filling holes
		MoveToEx(hDC, offsetTop, pointEnd.y, NULL);
		LineTo(hDC, pointEnd.x, pointEnd.y);
		for (j=offsetLeft; j<=pointStart.y; j++)
		{
			sPoint.x = pointStart.x;
			sPoint.y = j;
			ePoint.x = pointEnd.x;
			ePoint.y = pointEnd.y;

			MoveToEx(hDC, sPoint.x, sPoint.y, NULL);
			LineTo(hDC, ePoint.x, ePoint.y);
		}
		SelectObject(hDC, hOldPen);
		DeleteObject(hPen);
		offsetLeft = pointStart.y;
		offsetTop = pointEnd.x;

		// Start and end points on the right side
		pointStart.x = lpRect->right-i-2;
		if (pointStart.x < lpRect->left+1)
			pointStart.x = lpRect->left+1;
		pointStart.y = lpRect->bottom-2;
		pointEnd.x = lpRect->right-2;
		pointEnd.y = lpRect->bottom-(int)(angle*i)-2;
		if (pointEnd.y < lpRect->top+1)
			pointEnd.y = lpRect->top+1;

		// Right side
		hPen = CreatePen(PS_SOLID, 1, colorEnd);
		hOldPen = (HPEN)SelectObject(hDC, hPen);
		MoveToEx(hDC, pointStart.x, pointStart.y, NULL);
		LineTo(hDC, pointEnd.x, pointEnd.y);
		// Filling holes
		MoveToEx(hDC, pointEnd.x, offsetBottom, NULL);
		LineTo(hDC, pointEnd.x, pointEnd.y-1);
		for (j=offsetRight; j>=pointEnd.y; j--)
		{
			sPoint.x = pointStart.x;
			sPoint.y = pointStart.y;
			ePoint.x = pointEnd.x;
			ePoint.y = j;

			MoveToEx(hDC, sPoint.x, sPoint.y, NULL);
			LineTo(hDC, ePoint.x, ePoint.y);
		}
		SelectObject(hDC, hOldPen);
		DeleteObject(hPen);
		offsetRight = pointEnd.y;
		offsetBottom = pointEnd.y;
	}
}

void CGradient::BackwardDiagonalGradient(HDC hDC, LPRECT lpRect, COLORREF sColor, COLORREF eColor, BOOL bGamma, double gamma)
{
	// Gradient params
	int width = lpRect->right - lpRect->left - 1;
	int height = lpRect->bottom - lpRect->top - 1;
	double angle = (double)height / (double)width;

	// Draw gradient
	HPEN hPen = NULL;
	HPEN hOldPen = NULL;
	double percent;
	unsigned char sRed, sGreen, sBlue, eRed, eGreen, eBlue;
	COLORREF colorStart, colorEnd;
	int offsetLeft = lpRect->bottom - 2;
	int offsetRight = lpRect->top + 1;
	int offsetTop = lpRect->left + 1;
	int offsetBottom = lpRect->bottom - 1;
	POINT pointStart, pointEnd;
	POINT sPoint, ePoint;
	int i, j;
	for (i=0; i<=width; i++)
	{
		// Gradient color percent
		percent = 1 - (double)i/(double)(2*width);

		// Start color
		sRed = (unsigned char)(GetRValue(sColor)*percent) + (unsigned char)(GetRValue(eColor)*(1-percent));
		sGreen = (unsigned char)(GetGValue(sColor)*percent) + (unsigned char)(GetGValue(eColor)*(1-percent));
		sBlue = (unsigned char)(GetBValue(sColor)*percent) + (unsigned char)(GetBValue(eColor)*(1-percent));
		if (bGamma)
		{
			sRed = (unsigned char)(pow((double)sRed/255.0, gamma) * 255);
			sGreen = (unsigned char)(pow((double)sGreen/255.0, gamma) * 255);
			sBlue = (unsigned char)(pow((double)sBlue/255.0, gamma) * 255);
		}
		colorStart = RGB(sRed, sGreen, sBlue);

		// End color
		eRed = (unsigned char)(GetRValue(eColor)*percent) + (unsigned char)(GetRValue(sColor)*(1-percent));
		eGreen = (unsigned char)(GetGValue(eColor)*percent) + (unsigned char)(GetGValue(sColor)*(1-percent));
		eBlue = (unsigned char)(GetBValue(eColor)*percent) + (unsigned char)(GetBValue(sColor)*(1-percent));
		if (bGamma)
		{
			eRed = (unsigned char)(pow((double)eRed/255.0, gamma) * 255);
			eGreen = (unsigned char)(pow((double)eGreen/255.0, gamma) * 255);
			eBlue = (unsigned char)(pow((double)eBlue/255.0, gamma) * 255);
		}
		colorEnd = RGB(eRed, eGreen, eBlue);

		// Start and end points on the left side
		pointStart.x = lpRect->left + 1;
		pointStart.y = lpRect->bottom-(int)(angle*i)-2;
		if (pointStart.y < lpRect->top+1)
			pointStart.y = lpRect->top+1;
		pointEnd.x = lpRect->left+i+1;
		if (pointEnd.x >= lpRect->right-2)
			pointEnd.x = lpRect->right-2;
		pointEnd.y = lpRect->bottom-2;

		// Left side
		hPen = CreatePen(PS_SOLID, 1, colorStart);
		hOldPen = (HPEN)SelectObject(hDC, hPen);
		MoveToEx(hDC, pointStart.x, pointStart.y, NULL);
		LineTo(hDC, pointEnd.x, pointEnd.y);
		// Filling holes
		MoveToEx(hDC, offsetTop, pointEnd.y, NULL);
		LineTo(hDC, pointEnd.x, pointEnd.y);
		for (j=pointStart.y; j<=offsetLeft; j++)
		{
			sPoint.x = pointStart.x;
			sPoint.y = j;
			ePoint.x = pointEnd.x;
			ePoint.y = pointEnd.y;

			MoveToEx(hDC, sPoint.x, sPoint.y, NULL);
			LineTo(hDC, ePoint.x, ePoint.y);
		}
		SelectObject(hDC, hOldPen);
		DeleteObject(hPen);
		offsetLeft = pointStart.y;
		offsetTop = pointEnd.x;

		// Start and end points on the right side
		pointStart.x = lpRect->right-i-2;
		if (pointStart.x < lpRect->left+1)
			pointStart.x = lpRect->left+1;
		pointStart.y = lpRect->top+1;
		pointEnd.x = lpRect->right-2;
		pointEnd.y = lpRect->top+(int)(angle*i)+1;
		if (pointEnd.y > lpRect->bottom-2)
			pointEnd.y = lpRect->bottom-2;

		// Right side
		hPen = CreatePen(PS_SOLID, 1, colorEnd);
		hOldPen = (HPEN)SelectObject(hDC, hPen);
		MoveToEx(hDC, pointStart.x, pointStart.y, NULL);
		LineTo(hDC, pointEnd.x, pointEnd.y);
		// Filling holes
		MoveToEx(hDC, pointEnd.x, offsetBottom, NULL);
		LineTo(hDC, pointEnd.x, pointEnd.y+1);
		for (j=pointEnd.y; j>=offsetRight; j--)
		{
			sPoint.x = pointStart.x;
			sPoint.y = pointStart.y;
			ePoint.x = pointEnd.x;
			ePoint.y = j;

			MoveToEx(hDC, sPoint.x, sPoint.y, NULL);
			LineTo(hDC, ePoint.x, ePoint.y);
		}
		SelectObject(hDC, hOldPen);
		DeleteObject(hPen);
		offsetRight = pointEnd.y;
		offsetBottom = pointEnd.y;
	}
}

void CGradient::RadialGradient(HDC hDC, LPRECT lpRect, COLORREF sColor, COLORREF eColor, BOOL bCircle, BOOL bGamma, double gamma)
{
	// Gradient params
	int width = lpRect->right - lpRect->left - 1;
	int height = lpRect->bottom - lpRect->top - 1;
	int size = (width < height) ? width : height;

	// Fill background
	HBRUSH hBrush = CreateSolidBrush(sColor);
	RECT fillRect = {lpRect->left+1, lpRect->top+1, lpRect->right-1, lpRect->bottom-1};
	FillRect(hDC, &fillRect, hBrush);
	DeleteObject(hBrush);

	// Draw gradient
	HPEN hPen = NULL;
	HPEN hOldPen = NULL;
	double percent;
	unsigned char red, green, blue;
	COLORREF color;
	POINT pointStart, pointEnd;
	for (int i=0; i<size/2; i++)
	{
		// Gradient color percent
		percent = 1 - (double)i / (double)(size/2);

		// Gradient color
		red = (unsigned char)(GetRValue(sColor)*percent) + (unsigned char)(GetRValue(eColor)*(1-percent));
		green = (unsigned char)(GetGValue(sColor)*percent) + (unsigned char)(GetGValue(eColor)*(1-percent));
		blue = (unsigned char)(GetBValue(sColor)*percent) + (unsigned char)(GetBValue(eColor)*(1-percent));
		if (bGamma)
		{
			red = (unsigned char)(pow((double)red/255.0, gamma) * 255);
			green = (unsigned char)(pow((double)green/255.0, gamma) * 255);
			blue = (unsigned char)(pow((double)blue/255.0, gamma) * 255);
		}
		color = RGB(red, green, blue);

		if (bCircle)
		{
			// Start and end points
			pointStart.x = (lpRect->left + lpRect->right)/2 - (size/2-i) + 2;
			pointStart.y = (lpRect->top + lpRect->bottom)/2 - (size/2-i) + 2;
			pointEnd.x = (lpRect->left + lpRect->right)/2 + (size/2-i) - 2;
			pointEnd.y = (lpRect->top + lpRect->bottom)/2 + (size/2-i) - 2;
		}
		else
		{
			// Start and end points
			pointStart.x = (lpRect->left + lpRect->right)/2 - (width/2-i) + 2;
			pointStart.y = (lpRect->top + lpRect->bottom)/2 - (height/2-i) + 2;
			pointEnd.x = (lpRect->left + lpRect->right)/2 + (width/2-i) - 2;
			pointEnd.y = (lpRect->top + lpRect->bottom)/2 + (height/2-i) - 2;
		}

		// Gradient
		hPen = CreatePen(PS_SOLID, 2, color);
		hOldPen = (HPEN)SelectObject(hDC, hPen);
		Ellipse(hDC, pointStart.x, pointStart.y, pointEnd.x, pointEnd.y);
		SelectObject(hDC, hOldPen);
		DeleteObject(hPen);
	}
}

void CGradient::MulticolorHorizontalGradient(HDC hDC, LPRECT lpRect, COLORREF colors[], int numColors, BOOL bGamma, double gamma)
{
	if (numColors < 2)
		return;

	// Gradient params
	int width = lpRect->right - lpRect->left - 1;
	int height = lpRect->bottom - lpRect->top - 1;

	int offset = width / (numColors-1);
	for (int c=1; c<numColors; c++)
	{
		COLORREF sColor = colors[c-1];
		COLORREF eColor = colors[c];

		// Draw gradient
		HBRUSH hBrush = NULL;
		double percent;
		unsigned char red, green, blue;
		COLORREF color;
		RECT rect;
		for (int i=0; i<=offset; i++)
		{
			// Gradient color percent
			percent = 1 - (double)i / (double)(offset);

			// Gradient color
			red = (unsigned char)(GetRValue(sColor)*percent) + (unsigned char)(GetRValue(eColor)*(1-percent));
			green = (unsigned char)(GetGValue(sColor)*percent) + (unsigned char)(GetGValue(eColor)*(1-percent));
			blue = (unsigned char)(GetBValue(sColor)*percent) + (unsigned char)(GetBValue(eColor)*(1-percent));
			if (bGamma)
			{
				red = (unsigned char)(pow((double)red/255.0, gamma) * 255);
				green = (unsigned char)(pow((double)green/255.0, gamma) * 255);
				blue = (unsigned char)(pow((double)blue/255.0, gamma) * 255);
			}
			color = RGB(red, green, blue);

			// Gradient
			rect.left = lpRect->left + (c-1)*offset + i + 1;
			if (rect.left >= lpRect->right-2)
				rect.left = lpRect->right-2;
			rect.top = lpRect->top + 1;
			rect.right = rect.left + 1;
			rect.bottom = lpRect->bottom - 1;
			hBrush = CreateSolidBrush(color);
			FillRect(hDC, &rect, hBrush);
			DeleteObject(hBrush);
		}

		if (offset*(numColors-1) < width)
		{
			rect.left = lpRect->right - (width-offset*(numColors-1));
			rect.top = lpRect->top + 1;
			rect.right = lpRect->right - 1;
			rect.bottom = lpRect->bottom - 1;
			hBrush = CreateSolidBrush(colors[numColors-1]);
			FillRect(hDC, &rect, hBrush);
			DeleteObject(hBrush);
		}
	}
}

void CGradient::MulticolorVerticalGradient(HDC hDC, LPRECT lpRect, COLORREF colors[], int numColors, BOOL bGamma, double gamma)
{
	if (numColors < 2)
		return;

	// Gradient params
	int width = lpRect->right - lpRect->left - 1;
	int height = lpRect->bottom - lpRect->top - 1;

	int offset = height / (numColors-1);
	for (int c=1; c<numColors; c++)
	{
		COLORREF sColor = colors[c-1];
		COLORREF eColor = colors[c];

		int step = (int)(((double)offset/2)/255);
		if ( step == 0 )
			step = 1;

		// Draw gradient
		HBRUSH hBrush = NULL;
		HPEN hPen = NULL;
		HPEN hOldPen = NULL;
		double percent;
		unsigned char red, green, blue;
		COLORREF color;
		RECT rect;
		for (int i=0; i<=offset; i++)

⌨️ 快捷键说明

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