首页 文章

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

提问于
浏览
3

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

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

3 回答

  • 0

    FireMonkey中没有 FloodFill 函数等效,但您可以使用可填充的路径(TPathData) . 因此,您可以定义具有要填充的形状的路径,然后使用FMX.Graphics.TCanvas.FillPath进行内部绘制 .

  • 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

    我将这个旧的洪水填充代码(由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函数来优化此代码,但即使按原样,它对于大多数操作来说也足够快 .

相关问题