渐变填充 ( 积分: 100 )

  • 主题发起人 主题发起人 hwljerry
  • 开始时间 开始时间
H

hwljerry

Unregistered / Unconfirmed
GUEST, unregistred user!
procedure TForm1.Button1Click(Sender: TObject);
var
pts: array[0..3] of TPoint;
begin
pts[0] := Point(93, 107);
pts[1] := Point(193, 207);
pts[2] := Point(207, 193);
pts[3] := Point(107, 93);
Canvas.Polygon(pts);
end;
想要填充这个区域有什么好办法吗?
我希望也是按这个区域从左上到右下这样填充,不想要从左到右这样填充,从左到右网络上都是这样的代码可以找到。如果分不够可以加。。。。。
 
怎么用啊。能不能说的明白点呢。
 
楼主要的可是这效果?顺手写的
先复制代码 运行。如果不是你要的就不用仔细琢磨了。

uses Math;

procedure TForm1.Button2Click(Sender: TObject);
const
bmWidth = 300; //图象宽
bmHeight = 300; //图象高
srcColor = $00FF0000; //原颜色
dstColor = $000000FF; //目标色
DeepWidth = 422; //渐变宽度
DeepHeight= 422; //渐变高度
var
pts: array[0..3] of TPoint;
Bmp: TBitmap;
I, J: Integer;
PB : PByteArray;
fPerRX, fPerRY, fPerGX, fPerGY, fPerBX, fPerBY, fW: Single;
RValue, GValue, BValue: Byte;
begin
pts[0] := Point(93, 107);
pts[1] := Point(193, 207);
pts[2] := Point(207, 193);
pts[3] := Point(107, 93);
Bmp := TBitmap.Create;
Bmp.PixelFormat := pf32Bit;
Bmp.Width := bmWidth;
Bmp.Height:= bmHeight;
Bmp.Canvas.Brush.Color := clBlack;
Bmp.Canvas.Polygon(pts);

fW := sqrt(DeepWidth * DeepWidth + DeepHeight * DeepHeight); //计算渐变长度
RValue := GetRValue(srcColor);
GValue := GetGValue(srcColor);
BValue := GetBValue(srcColor);
fPerRX := (RValue - GetRValue(dstColor))/fW; //计算每像素X方向的红色衰减值
fPerRY := (RValue - GetRValue(dstColor))/fW; //计算每像素Y方向的红色衰减值
fPerGX := (GValue - GetGValue(dstColor))/fW; //计算每像素X方向的绿色衰减值
fPerGY := (GValue - GetGValue(dstColor))/fW; //计算每像素Y方向的绿色衰减值
fPerBX := (BValue - GetBValue(dstColor))/fW; //计算每像素X方向的黄色衰减值
fPerBY := (BValue - GetBValue(dstColor))/fW; //计算每像素Y方向的黄色衰减值
for J := 0 to Bmp.Height - 1 do
begin
PB := Bmp.ScanLine[J];
for I := 0 to Bmp.Width - 1 do
begin
if (PB[I * 4 + 2] <> $00) or (PB[I * 4 + 1] <> $00) or (PB[I * 4] <> $00) then
continue;
PB[I * 4 + 3] := $FF; //alpha gdi不好弄alpha 所以就这样了
PB[I * 4 + 2] := max(0, Round(RValue - fPerRY * J - fPerRX * I)); //r
PB[I * 4 + 1] := max(0, Round(GValue - fPerGY * J - fPerGX * I)); //g
PB[I * 4] := max(0, Round(BValue - fPerBY * J - fPerBX * I)); //b
end;
end;
Canvas.Draw(0, 0, Bmp);
Bmp.Free;
end;
 
DeepWidth = 422; //渐变宽度
DeepHeight= 422; //渐变高度
这两个参数你是按什么来设置呢。为什么设为422?
 
你也可设置成图象宽度和图象高度.因为有些时候渐变的范围不等于图象的矩形区域.
 
用GDI的话。没有BMP,那么宽度和长度这个该怎么改啊?
 
渐变填充及delphi中相关部分的修正 [原]

sundytu
12:38 PM


在windows98后的MS操作系统中,新增了很多图形处理函数,他们都位于msimg32.dll中,利用这些函数可以快速得到很多很炫目的效果,并且自己不要做什么工作,由系统去做,我们要做的只是告诉它如何画就可以了,这里介绍一下渐变填充函数的应用。
下面是这个函数的声明,其实在delphi中有这个函数的声明:GradientFill,但使用过程中我发现它的数据结构与MSDN上最新的结构定义不同,所以这里改了一下:
TriVertexSundy = record
x: DWORD;
y: DWORD;
Red: WORD;
Green: WORD;
Blue: WORD;
Alpha: WORD;
end;

function GradientFillEx(DC: HDC; var Vertex: TriVertexSundy; NumVertex: DWORD; Mesh: Pointer; NumMesh, Mode: DWORD): boolean; stdcall;
external 'msimg32.dll' name 'GradientFill';//这个函数的参数定义大家可以参照MSDN的说明,很简单的!
然后我们就可以利用这个函数做出很多炫目的效果了,这里的代码只是做了横向的矩形渐变填充,对于三角的渐变和纵向渐变填充可以通过这个例子以及MSDN的说明举一反三。
下面是源代码:
interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ExtCtrls;

type
TriVertexSundy = record
x: DWORD;
y: DWORD;
Red: WORD;
Green: WORD;
Blue: WORD;
Alpha: WORD;
end;

TForm1 = class(TForm)
Timer1: TTimer;
Button1: TButton;
procedure Button1Click(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure Timer1Timer(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

function GradientFillEx(DC: HDC; var Vertex: TriVertexSundy; NumVertex: DWORD; Mesh: Pointer; NumMesh, Mode: DWORD): boolean; stdcall;
external 'msimg32.dll' name 'GradientFill';

var
Form1: TForm1;
l: integer = 0;
memDC: HDC;
memBmp, tmpbmp: HBitMap;
implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var r: TRect;
vert: array[0..3] of TriVertexSundy;
gTRi: array[0..1] of TGradientRect;
DC: HDC;
begin
DC := GetDC(0);
if memBmp <> 0 then
begin
SelectObject(memdc, tmpbmp);
deleteobject(memBmp);
end;
if memdc <> 0 then DeleteDC(memdc);
memDC := CreateCompatibleDC(DC);
memBmp := CreateCompatibleBitmap(DC, 200, 20);
releaseDC(0, DC);
tmpbmp := SelectObject(memDC, membmp);
vert[0].x := 0;
vert[0].y := 0;
vert[0].Red := $FFFF;
vert[0].Green := $FFFF;
vert[0].Blue := $FFFF;
vert[0].Alpha := 0;

vert[1].x := 100;
vert[1].y := 20;
vert[1].Red := 0;
vert[1].Green := 0;
vert[1].Blue := $FFFF;
vert[1].Alpha := 0;

vert[2].x := 100;
vert[2].y := 0;
vert[2].Red := 0;
vert[2].Green := 0;
vert[2].Blue := $FFFF;
vert[2].Alpha := 0;

vert[3].x := 200;
vert[3].y := 20;
vert[3].Red := $FFFF;
vert[3].Green := $FFFF;
vert[3].Blue := $FFFF;
vert[3].Alpha := 0;

gTRi[0].UpperLeft := 0;
gTRi[0].LowerRight := 1;
gTRi[1].UpperLeft := 2;
gTRi[1].LowerRight := 3;
GradientFillEx(memDC, vert[0], 4, @gTRI, 2, GRADIENT_FILL_Rect_H);
Timer1.Enabled := not Timer1.Enabled;
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
if memBmp <> 0 then
begin
SelectObject(memdc, tmpbmp);
deleteobject(memBmp);
end;
if memdc <> 0 then DeleteDC(memdc);
end;

procedure TForm1.Timer1Timer(Sender: TObject);
var DC: HDC;
begin
DC := getDC(Handle);
bitblt(DC, 0, 0, l, 20, memdc, 200 - l, 0, SRCCOPY);
bitblt(DC, l, 0, 200 - l, 20, memdc, 0, 0, SRCCOPY);
l := (l + 10) mod 200;
ReleaseDC(Handle, DC);
end;

end.
 
要想简单还是gdi+

一个渐变画刷就搞定了.!

uses gdipapi, gdipobj;

procedure TForm1.Button1Click(Sender: TObject);
var
GPGraphic: TGPGraphics;
GradientBrush : TGPLinearGradientBrush;
pts: array[0..3] of TGPPointF;
begin
GPGraphic := TGPGraphics.Create(Canvas.Handle);
GradientBrush := TGPLinearGradientBrush.Create(MakePoint(93, 107), MakePoint(207, 193), $FFFF0000, $FF0000FF);

pts[0] := MakePoint(93.0, 107.0);
pts[1] := MakePoint(193.0, 207.0);
pts[2] := MakePoint(207.0, 193.0);
pts[3] := MakePoint(107.0, 93.0);

GPGraphic.FillPolygon(GradientBrush, PGPPointF(@pts[0]), 4);
GradientBrush.Free;
GPGraphic.Free;
end;
 

Similar threads

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