[英]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.