【问题标题】:Is there an equivalent to FloodFill in FMX for a TBitmap?TBitmap 的 FMX 中是否有相当于 FloodFill 的方法?
【发布时间】:2014-04-02 13:45:18
【问题描述】:

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

在 FMX 中是否有与此功能等效的功能?

【问题讨论】:

    标签: delphi c++builder firemonkey vcl


    【解决方案1】:

    根据 RRUZ 的回答和 Anthony 的回答,我做了这个代码:

    Procedure TForm1.FloodFill(BitmapData:TBitmapData; X, Y:Integer;  OldColor, NewColor: TAlphaColor);
    var
      Current: TAlphaColor;
    begin
      Current := BitmapData.GetPixel(X, Y);
      if Current = OldColor then begin
        BitmapData.SetPixel(X,Y,NewColor);
        FloodFill(BitmapData, X+1, Y, OldColor, NewColor);
        FloodFill(BitmapData, X-1, Y, OldColor, NewColor);
        FloodFill(BitmapData, X, Y+1, OldColor, NewColor);
        FloodFill(BitmapData, X, Y-1, OldColor, NewColor);
      end;
    end;
    

    还有一个使用示例:

    procedure TForm1.Image1MouseUp(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Single);
    var
      MyBmpData: TBitmapData;
      OldColor, NewColor: TAlphaColor;
      ix, iy: integer;
    begin
      Image1.Bitmap.Canvas.Bitmap.Map(TMapAccess.ReadWrite, MyBmpData);
    
      ix := round(X); iy := Round(Y);
      OldColor := MyBmpData.GetPixel(ix, iy);
      NewColor := ColorComboBox1.Color; // or use some other source for a new color
      FloodFill(MyBmpData, ix, iy, OldColor, NewColor) ;
    
      Image1.Bitmap.Canvas.Bitmap.Unmap(MyBmpData);
    end;
    

    【讨论】:

    • 欢迎来到 StackOverflow!请在您的代码中添加一些文本来描述它在做什么。卡在这里的用户会复制,粘贴和忘记,但最好学习一些东西:)
    • 如果我没看错这个函数,它会用替换颜色对某种颜色进行泛光填充,当它到达不同颜色或位图边缘时停止?
    • 是的,我认为这就是所谓的洪水填充。专门使用 FsSurface 进行填埋
    【解决方案2】:

    FireMonkey 中没有等效的FloodFill 函数,但您可以使用可以填充的路径(TPathData)。所以你可以用要填充的形状定义一个路径,然后 用FMX.Graphics.TCanvas.FillPath做室内画。

    【讨论】:

    • 为了向 VCL FloodFill 复制类似的相关(在我的情况下)功能,我编写了一个简单的 4 路 FloodFill 函数,使用 TBitmapData 来获取和设置像素。
    【解决方案3】:

    我转换了这个旧的填充代码(由 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 函数替换为扫描线和直接内存访问来优化此代码,但即使按原样,它对于大多数操作来说也足够快。

    【讨论】:

      猜你喜欢
      • 2015-09-18
      • 2010-11-24
      • 2011-03-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多