对于TBitmap,是否有相当于FMX的FloodFill?

时间:2014-04-02 13:45:19

标签: delphi c++builder firemonkey vcl

我正在从VCL转换为FMX。在VCL中,TBitmap的TCanvas中有一个名为FloodFill的函数,它允许TBitmap的画布充满特定颜色,直到位图画布上达到另一种特定颜色。

FMX中是否有与此功能相同的功能?

3 个答案:

答案 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函数来优化此代码,但即使按原样,它对于大多数操作来说也足够快。