简体   繁体   English

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

[英]Is there an equivalent to FloodFill in FMX for a TBitmap?

I am converting from VCL to FMX. 我正在从VCL转换为FMX。 In VCL, there was a function in a TBitmap's TCanvas called FloodFill, which allowed for a TBitmap's canvas to be flooded with a specific color, until another specific color was reached on the bitmap's canvas. 在VCL中,TBitmap的TCanvas中有一个名为FloodFill的函数,它允许TBitmap的画布充满特定颜色,直到位图画布上达到另一种特定颜色。

Is there an equivalent to this function in FMX? FMX中是否有与此功能相同的功能?

Base on RRUZ's answer and Anthony's reply, I made this code: 根据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;

And a usage sample: 一个用法示例:

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;

There is not a FloodFill function equivalent in FireMonkey, but you can use a path( TPathData ) which can be filled. FireMonkey中没有与FloodFill函数等效的FloodFill ,但您可以使用可填充的路径( TPathData )。 So you could define a path with the shape to fill, and then use the FMX.Graphics.TCanvas.FillPath to do the interior painting. 因此,您可以定义具有要填充的形状的路径,然后使用FMX.Graphics.TCanvas.FillPath进行内部绘制。

I converted this old floodfill code (posted by Jon Lennart Berg) to support Firemonkey bitmaps: 我转换了这个旧的洪水填充代码(由Jon Lennart Berg发布)来支持Firemonkey位图:
https://groups.google.com/forum/#!topic/borland.public.delphi.graphics/84pyiclLTvg 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;

This code could be optimized by replacing the GetPixel/SetPixel functions with scanlines and direct memory access, but even as-is, it's fast enough for most operations. 可以通过将扫描线和直接内存访问替换为GetPixel / SetPixel函数来优化此代码,但即使按原样,它对于大多数操作来说也足够快。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM