颜色渐变问题(50分)

  • 主题发起人 主题发起人 djptony
  • 开始时间 开始时间
D

djptony

Unregistered / Unconfirmed
GUEST, unregistred user!
如何实现从一种颜色到另一种颜色的渐变?
我看了dfw上的一个贴子
http://www.delphibbs.com/delphibbs/dispq.asp?lid=1114265
算法不正确。谁又比较好的算法?
 
我有只不过算法太累赘不过可以copy
 
djptony@netease.com
参考一下
 
终极渐变填充解决方案:
由Windows提供的渐变填充方法,属于非公开函数。
定义在MSIMG32.DLL中,Win98以上可采用。

函数定义:
BOOL GradientFill( HDC hdc, // DC句柄
PTRIVERTEX pVertex, // 顶点矩阵
ULONG dwNumVertex, // 顶点个数
PVOID pMesh, // 填充渐变梯度矩阵
ULONG dwNumMesh, // 填充渐变梯度矩阵尺寸
ULONG dwMode // 填充方式
);

其它详细信息可以从MSDN上查找,用GradientFill作关键词搜索即可。
GradientFill不仅速度快,还可以实现无数特技,只要你能想到。

我只是在BCB中用它,没提供它的Delphi描述,好事者不防试试。 
在BCB中所有信息定义在WinGdi.h文件内,如果不以调DLL的方式使用,则需要将MsImg32.lib加到工程内,应该在BCB安装目录的LIB/PSDK下。
下面是用BCB写的两个示例:
//---------------------------------------------------------------------------
// 矩形填充
void __fastcall GradientFillRect( HDC dc, TRect& rect, TColor beg,
TColor end, TOGGradientRectMode mode )
{

if( mode == ogrmVert || mode == ogrmHori )
{
TRIVERTEX vert[2] ;
GRADIENT_RECT gRect;
vert [0] .x = rect.Left;
vert [0] .y = rect.Top;
vert [0] .Red = GetRValue( beg ) * 0x100;
vert [0] .Green = GetGValue( beg ) * 0x100;
vert [0] .Blue = GetBValue( beg ) * 0x100;
vert [0] .Alpha = 0x0000;

vert [1] .x = rect.Right;
vert [1] .y = rect.Bottom;
vert [1] .Red = GetRValue( end ) * 0x100;
vert [1] .Green = GetGValue( end ) * 0x100;
vert [1] .Blue = GetBValue( end ) * 0x100;
vert [1] .Alpha = 0x0000;

gRect.UpperLeft = 0;
gRect.LowerRight = 1;

ULONG dwMode = (mode == ogrmVert)? GRADIENT_FILL_RECT_V : GRADIENT_FILL_RECT_H;

#ifdef SEM_USE_MSIMG32DIRECT
GradientFill( dc, vert, 2, &gRect, 1, dwMode );
#else
HINSTANCE DLLHandle = LoadLibrary("MSIMG32.DLL");
if( DLLHandle != NULL )
{
FGradientFill proc = (FGradientFill)GetProcAddress(DLLHandle,"GradientFill");
if( proc )
proc(dc, vert, 2, &gRect, 1, dwMode);

FreeLibrary( DLLHandle );
}
#endif
}
else if( mode == ogrmCenter )
{
TPoint p[9];
TColor c[9];

p[0].x = (rect.Left + rect.Right) / 2;
p[0].y = (rect.Top + rect.Bottom) / 2;
p[1].x = rect.Left;
p[1].y = rect.Top;
p[2].x = rect.Right;
p[2].y = rect.Top;
p[3].x = rect.Right;
p[3].y = rect.Top;
p[4].x = rect.Right;
p[4].y = rect.Bottom;
p[5].x = rect.Right;
p[5].y = rect.Bottom;
p[6].x = rect.Left;
p[6].y = rect.Bottom;
p[7].x = rect.Left;
p[7].y = rect.Bottom;
p[8].x = rect.Left;
p[8].y = rect.Top;

c[0] = beg;
for( int i = 1; i < 9; i++ )
c = end;

GradientFillTriangle( dc, p, c, 9 );
}
}
//---------------------------------------------------------------------------
// 三角形填充,可用于渲染任何形状图形或进行三维渲染。
void __fastcall GradientFillTriangle( HDC dc, Windows::TPoint *points,
Graphics::TColor *colors,
int num )
{

if( num < 3 )
return;

TRIVERTEX *vert = new TRIVERTEX[num] ;
int nTri = (num - 1) / 2;
GRADIENT_TRIANGLE *gTri = new GRADIENT_TRIANGLE[nTri];
try
{
TColor color;
for( int i = 0; i < num; i++ )
{
color = colors;
vert .x = points.x;
vert .y = points.y;
vert .Red = GetRValue( color ) * 0x100;
vert .Green = GetGValue( color ) * 0x100;
vert .Blue = GetBValue( color ) * 0x100;
vert .Alpha = 0x0000;
}

for( int i = 0; i < nTri; i++ )
{
gTri.Vertex1 = 0;
gTri.Vertex2 = i * 2 + 1;
gTri.Vertex3 = i * 2 + 2;
}

#ifdef SEM_USE_MSIMG32DIRECT
GradientFill( dc, vert, num, gTri, nTri, GRADIENT_FILL_TRIANGLE );
#else
HINSTANCE DLLHandle = LoadLibrary("MSIMG32.DLL");
if( DLLHandle != NULL )
{
FGradientFill proc = (FGradientFill)GetProcAddress(DLLHandle,"GradientFill");
if( proc )
proc(dc, vert, num, gTri, nTri, GRADIENT_FILL_TRIANGLE);

FreeLibrary( DLLHandle );
}
#endif
}
__finally
{
delete[] vert;
delete[] gTri;
}
}
 
谢谢apw,接分
 
接受答案了.
 

Similar threads

S
回复
0
查看
3K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
2K
SUNSTONE的Delphi笔记
S
I
回复
0
查看
768
import
I
D
回复
0
查看
858
DelphiTeacher的专栏
D
后退
顶部