我想实现windows画板中颜料桶的功能,可是改变染色颜色的时候总是出错谁能告诉我是怎么回事?unit Unit1;interfaceuses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ExtCtrls, StdCtrls, Buttons;type
TForm1 = class(TForm)
Image1: TImage;
Shape1: TShape;
ColorDialog1: TColorDialog;
procedure Shape1MouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
procedure Image1MouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
private
{ Private declarations }
public
{ Public declarations }
procedure ColorFill(DestBmp:TBitmap;x,y:integer;Red,Green,Blue,NewRed,NewGreen,NewBlue:byte);
end;var
Form1: TForm1;implementation{$R *.dfm}//颜料桶
procedure TForm1.ColorFill(DestBmp:TBitmap;x,y:integer;Red,Green,Blue,NewRed,NewGreen,NewBlue:byte);
var
DestRGB: pRGBTriple;
i,j:integer;
begin
if (NewRed = Red) and (NewBlue = Blue) and (NewGreen = Green) then
else
if (y-1 > 1) and (x-1 >1) and (y+1 < DestBmp.Height) and (x+1 <DestBmp.Width) then
begin
DestBmp.PixelFormat:=pf24Bit;
for i := 0 to 2 do
begin
DestRGB :=DestBmp.ScanLine[i+y-1];
for j := 0 to DestBmp.Width - 1 do
begin
if j = x-1 then
begin
if (DestRGB.rgbtRed = Red)and (DestRGB.rgbtGreen = Green)and (DestRGB.rgbtBlue = Blue) then
begin
DestRGB.rgbtRed := NewRed;
DestRGB.rgbtGreen := NewGreen;
DestRGB.rgbtBlue := NewBlue;
ColorFill(DestBmp,j,i+y-1,Red,Green,Blue,NewRed,NewGreen,NewBlue);
end;
end;
if j = x then
begin
if (DestRGB.rgbtRed = Red)and (DestRGB.rgbtGreen = Green)and (DestRGB.rgbtBlue = Blue) then
begin
DestRGB.rgbtRed := NewRed;
DestRGB.rgbtGreen := NewGreen;
DestRGB.rgbtBlue := NewBlue;
ColorFill(DestBmp,j,i+y-1,Red,Green,Blue,NewRed,NewGreen,NewBlue);
end;
end;
if j = x+1 then
begin
if (DestRGB.rgbtRed = Red)and (DestRGB.rgbtGreen = Green)and (DestRGB.rgbtBlue = Blue) then
begin
DestRGB.rgbtRed := NewRed;
DestRGB.rgbtGreen := NewGreen;
DestRGB.rgbtBlue := NewBlue;
ColorFill(DestBmp,j,i+y-1,Red,Green,Blue,NewRed,NewGreen,NewBlue);
end;
end;
Inc(DestRGB);
end;
end;
DestBmp.Assign(DestBmp);
end;
end;procedure TForm1.Shape1MouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
if form1.ColorDialog1.Execute then
shape1.Brush.Color := Form1.ColorDialog1.Color;
end;procedure TForm1.Image1MouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
var
i:Tcolor;
Red,Green,Blue:byte;
NewRed,NewGreen,NewBlue:byte;
begin
i := Image1.Canvas.Pixels[x, y];
Blue:= GetBValue(i);
Green:= GetGValue(i);
Red:= GetRValue(i);
NewRed:= GetRValue(Shape1.Brush.Color);
NewGreen:= GetGValue(Shape1.Brush.Color);
NewBlue:= GetBValue(Shape1.Brush.Color);
ColorFill(image1.Picture.Bitmap,x,y,Red,Green,Blue,NewRed,NewGreen,NewBlue);
end;end.
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ExtCtrls, StdCtrls, Buttons;type
TForm1 = class(TForm)
Image1: TImage;
Shape1: TShape;
ColorDialog1: TColorDialog;
procedure Shape1MouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
procedure Image1MouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
private
{ Private declarations }
public
{ Public declarations }
procedure ColorFill(DestBmp:TBitmap;x,y:integer;Red,Green,Blue,NewRed,NewGreen,NewBlue:byte);
end;var
Form1: TForm1;implementation{$R *.dfm}//颜料桶
procedure TForm1.ColorFill(DestBmp:TBitmap;x,y:integer;Red,Green,Blue,NewRed,NewGreen,NewBlue:byte);
var
DestRGB: pRGBTriple;
i,j:integer;
begin
if (NewRed = Red) and (NewBlue = Blue) and (NewGreen = Green) then
else
if (y-1 > 1) and (x-1 >1) and (y+1 < DestBmp.Height) and (x+1 <DestBmp.Width) then
begin
DestBmp.PixelFormat:=pf24Bit;
for i := 0 to 2 do
begin
DestRGB :=DestBmp.ScanLine[i+y-1];
for j := 0 to DestBmp.Width - 1 do
begin
if j = x-1 then
begin
if (DestRGB.rgbtRed = Red)and (DestRGB.rgbtGreen = Green)and (DestRGB.rgbtBlue = Blue) then
begin
DestRGB.rgbtRed := NewRed;
DestRGB.rgbtGreen := NewGreen;
DestRGB.rgbtBlue := NewBlue;
ColorFill(DestBmp,j,i+y-1,Red,Green,Blue,NewRed,NewGreen,NewBlue);
end;
end;
if j = x then
begin
if (DestRGB.rgbtRed = Red)and (DestRGB.rgbtGreen = Green)and (DestRGB.rgbtBlue = Blue) then
begin
DestRGB.rgbtRed := NewRed;
DestRGB.rgbtGreen := NewGreen;
DestRGB.rgbtBlue := NewBlue;
ColorFill(DestBmp,j,i+y-1,Red,Green,Blue,NewRed,NewGreen,NewBlue);
end;
end;
if j = x+1 then
begin
if (DestRGB.rgbtRed = Red)and (DestRGB.rgbtGreen = Green)and (DestRGB.rgbtBlue = Blue) then
begin
DestRGB.rgbtRed := NewRed;
DestRGB.rgbtGreen := NewGreen;
DestRGB.rgbtBlue := NewBlue;
ColorFill(DestBmp,j,i+y-1,Red,Green,Blue,NewRed,NewGreen,NewBlue);
end;
end;
Inc(DestRGB);
end;
end;
DestBmp.Assign(DestBmp);
end;
end;procedure TForm1.Shape1MouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
if form1.ColorDialog1.Execute then
shape1.Brush.Color := Form1.ColorDialog1.Color;
end;procedure TForm1.Image1MouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
var
i:Tcolor;
Red,Green,Blue:byte;
NewRed,NewGreen,NewBlue:byte;
begin
i := Image1.Canvas.Pixels[x, y];
Blue:= GetBValue(i);
Green:= GetGValue(i);
Red:= GetRValue(i);
NewRed:= GetRValue(Shape1.Brush.Color);
NewGreen:= GetGValue(Shape1.Brush.Color);
NewBlue:= GetBValue(Shape1.Brush.Color);
ColorFill(image1.Picture.Bitmap,x,y,Red,Green,Blue,NewRed,NewGreen,NewBlue);
end;end.
你的思路有问题,完全可以不这样做的你再想想看,我就不说了。
方法有问题,
完全可以不这么做的,你想想看,我就不说了。
实际上,我的意思是找出边界,然后用Polygon来填充颜色。
这样你可以设计不递归的算法,具体的,你可以沿着x轴找到(x,y)上方的那个边界点(x0,y0),然后沿着这个点把整个线找到,传入到lpPoints,就搞定了。建议在函数里面分开向各个方向的小函数,譬如向右上方找下一个点,这个点必须与你的区域相连接(颜色同),还必须是边界点(周围有不同颜色点),找到切点的时候必须换方向,当有点和(x0,y0)相连的时候就结束。思路就是这样。BOOL Polygon(
HDC hdc, // handle to device context
CONST POINT *lpPoints, // pointer to polygon's vertices
int nCount // count of polygon's vertices
);