我正在从VCL转换为FMX。在VCL中,TBitmap的TCanvas中有一个名为FloodFill的函数,它允许TBitmap的画布充满特定颜色,直到位图画布上达到另一种特定颜色。
FMX中是否有与此功能相同的功能?
答案 0 :(得分:2)
根据RRUZ的回答和Anthony的回复,我制作了这段代码:
Procedure TForm1.FloodFill(BitmapData:TBitmapData; X, Y:Integer; Old, Fill: TColor);
var
Current:integer;
begin
Current := BitmapData.GetPixel(X,Y);
if Current = Old then begin
BitmapData.SetPixel(X,Y,Fill);
FloodFill(BitmapData,X+1,Y,Old,Fill);
FloodFill(BitmapData,X-1,Y,Old,Fill);
FloodFill(BitmapData,X,Y+1,Old,Fill);
FloodFill(BitmapData,X,Y-1,Old,Fill);
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
var
MyBmpData:TBitmapData;
begin
Image1.Bitmap.Canvas.Bitmap.Map(TMapAccess.ReadWrite,MyBmpData);
FloodFill(MyBmpData,100,100,TAlphaColor(TAlphaColorRec.Lightgray),
TAlphaColor(TAlphaColorRec.Red)) ;
Image1.Bitmap.Canvas.Bitmap.Unmap(MyBmpData);
end;
答案 1 :(得分:1)
FireMonkey中没有等效的FloodFill
函数,但您可以使用可填充的路径(TPathData)。因此,您可以定义具有要填充的形状的路径,然后
使用FMX.Graphics.TCanvas.FillPath
进行室内绘画。
答案 2 :(得分:0)
我转换了这个旧的洪水填充代码(由Jon Lennart Berg发布)以支持Firemonkey位图:
https://groups.google.com/forum/#!topic/borland.public.delphi.graphics/84pyiclLTvg
procedure Bitmap_FloodFill(fBitmap: TBitmap; StartX,StartY : Integer; FillColor: TAlphaColor);
var
fBitmapData : TBitmapData;
X, Y : Integer;
ReplaceColor : TAlphaColor;
Stack : Array of TPoint;
fHeight : Integer;
fWidth : Integer;
procedure PutInStack(X, Y: Integer);
begin
SetLength(Stack, Length(Stack)+1);
Stack[Length(Stack)-1] := Point(X, Y);
end;
procedure GetFromStack(var X, Y: Integer);
begin
X := Stack[Length(Stack)-1].X;
Y := Stack[Length(Stack)-1].Y;
SetLength(Stack, Length(Stack)-1);
end;
begin
X := StartX;
Y := StartY;
fHeight := fBitmap.Height;
fWidth := fBitmap.Width;
if (X >= fWidth) or (Y >= fHeight) then Exit;
If fBitmap.Map(TMapAccess.ReadWrite,fBitmapData) then
Try
ReplaceColor := fBitmapData.GetPixel(X,Y);
If ReplaceColor <> FillColor then
Begin
PutInStack(X,Y);
While Length(Stack) > 0 do
Begin
GetFromStack(X,Y);
While (X > 0) and (fBitmapData.GetPixel(X-1, Y) = ReplaceColor) do Dec(X);
While (X < fWidth) and (fBitmapData.GetPixel(X , Y) = ReplaceColor) do
Begin
if Y > 0 then If fBitmapData.GetPixel(X, Y-1) = ReplaceColor then PutInStack(X, Y-1);
if Y+1 < fHeight then If fBitmapData.GetPixel(X, Y+1) = ReplaceColor then PutInStack(X, Y+1);
fBitmapData.SetPixel(X,Y,FillColor);
Inc(X);
End;
End;
End;
Finally
fBitmap.Canvas.Bitmap.Unmap(fBitmapData);
End;
end;
可以通过将扫描线和直接内存访问替换为GetPixel / SetPixel函数来优化此代码,但即使按原样,它对于大多数操作来说也足够快。