在文章《GDI矩形立体渐变、矩形放射渐变和矩形平面放射渐变原理以及代码实现》已经实现了矩形的渐变效果。这里来实现下圆形的渐变放射效果。
先来看看效果图吧:
1.正圆型中心渐变,向外收缩,球体效果
2.向外变亮的发射性渐变效果
3.横向椭圆渐变
4.纵向椭球渐变效果
渐变的实现还是和矩形的一样,是一圈圈的画图。矩形是一圈圈的画矩形,圆形是一圈圈的画圆或者椭圆,随着颜色的渐变,就形成了这样的效果。
下面是函数的声明:
void GradientLinearCircle(CDC* pDC,CRect rt,COLORREF clr1,COLORREF clr2,int len,bool swap)
函数参数说明,参见《GDI矩形立体渐变、矩形放射渐变和矩形平面放射渐变原理以及代码实现》。
下面是函数的使用示例:
CDC *pDC = GetDC();
CRect rtClient(50,50,300,400);
GradientLinearCircle(pDC,rtClient,RGB(255,255,10),RGB(0,0,255),250,false);
下面是函数的实现代码:
void GradientLinearCircle(CDC* pDC,CRect rt,COLORREF clr1,COLORREF clr2,int len,bool swap)
{
//使用内存DC来加速绘制,防止闪烁
CDC dcMem;
dcMem.CreateCompatibleDC(pDC);
CBitmap bmp;
bmp.CreateCompatibleBitmap(pDC,rt.Width(),rt.Height());
dcMem.SelectObject(&bmp);
//开始内存绘制
if (swap)
{
COLORREF clrTmp = clr1;
clr1 = clr2;
clr2 = clrTmp;
}
//rtTmp用于绘制,rt用于画布
CRect rtTmp(0,0,rt.Width(),rt.Height());
rtTmp.left += len;
rtTmp.top += len;
rtTmp.right -= len;
rtTmp.bottom -= len;
int width = rtTmp.Width();
int height = rtTmp.Height();
int r1 = GetRValue(clr1);
int r2 = GetRValue(clr2);
int g1 = GetGValue(clr1);
int g2 = GetGValue(clr2);
int b1 = GetBValue(clr1);
int b2 = GetBValue(clr2);
int rSpan = r2 - r1;
int gSpan = g2 - g1;
int bSpan = b2 - b1;
int len_clr=0;
dcMem.SelectStockObject(NULL_BRUSH);
for (int i=0;i<len;i++)
{
COLORREF clr = RGB(r1+(i*rSpan)/len,g1+(i*gSpan)/len,b1+(i*bSpan)/len);
CBrush brush(clr);
rtTmp.InflateRect(1,1,1,1);
CPen pen(PS_SOLID,2,clr);
dcMem.SelectObject(&pen);
dcMem.Ellipse(&rtTmp);
}
CFont font;
font.CreatePointFont(100,_T("微软雅黑"));
dcMem.SelectObject(&font);
dcMem.SetBkMode(TRANSPARENT);
dcMem.SetTextColor(RGB(0,0,0));
dcMem.DrawText(_T("C++技术网www.cjjjs.com 微信公众号:cpp_coder"),&rtTmp,DT_CENTER|DT_VCENTER|DT_SINGLELINE);
//将内存的数据一次性贴到设备DC中
pDC->BitBlt(rt.left,rt.top,rt.Width(),rt.Height(),&dcMem,0,0,SRCCOPY);
bmp.DeleteObject();
dcMem.DeleteDC();
}
有图有代码,有真相。代码的细节就不细说了。