Floodfill für TBitmap

Für Probleme bezüglich Grafik, Audio, GL, ACS, ...
Antworten
Benutzeravatar
corpsman
Lazarusforum e. V.
Beiträge: 1619
Registriert: Sa 28. Feb 2009, 08:54
OS, Lazarus, FPC: Linux Mint Mate, Lazarus GIT Head, FPC 3.0
CPU-Target: 64Bit
Wohnort: Stuttgart
Kontaktdaten:

Floodfill für TBitmap

Beitrag von corpsman »

Hossa,

Da ich nach einem Floodfill Algorithmus gesucht habe und im Forum nichts außer OpBitmap gefunden habe, habe ich mir mal erlaubt eine Art Minimal Floodfill für TBitmap zu aus der OPBitmap Version zu extrahieren.

Ich weis, dass diese Version nicht vollständig ist, aber besser wie nichts, in meinen von Delphi Portierten Projekten Funktioniert es ;)

Code: Alles auswählen

(*
Benutzung :
Orginal :
Bitmap.brush.color := color;
Bitmap.pen.color := color;
Bitmap.FloodFill(bitmap, x, y, bitmap.canvas.pixels[x,y] , fsBorder);
 
Floodfill2 :
 
FloodFill2(bitmap, x, y, color, fsBorder);
 
// ACHTUNG Fillstyle wird Ignoriert.
*)
 
Procedure FloodFill2(Var Bitmap: TBitmap; x_, y_: Integer; FillColor: TColor; FillStyle: TFillStyle);
Var
  Stack: Array Of TPoint;
  Stackp: Integer;
 
  x, y: Integer;
 
  Procedure PutInStack(X, Y: Integer);
  Begin
    inc(stackp);
    If Stackp > high(stack) Then Begin
      // Blockweise Vor Allokierung
      SetLength(Stack, high(Stack) + 1025);
    End;
    Stack[stackp] := Point(X, Y);
  End;
 
  Procedure GetFromStack(Var X, Y: Integer);
  Begin
    X := Stack[stackp].X;
    Y := Stack[stackp].Y;
    dec(stackp);
  End;
 
Var
 
  TempIntfImg: TLazIntfImage;
  ImgHandle, ImgMaskHandle: HBitmap;
 
  Function ColorInRange(c1, c2: TFPColor): Boolean;
  Begin
    result := (c1.red = c2.red) And
      (c1.green = c2.green) And
      (c1.blue = c2.blue);
  End;
 
Var
 
  FillColor2, ReplaceColor: TFPColor;
 
Begin
  X := X_;
  Y := Y_;
  If (X >= Bitmap.Width) Or (Y >= Bitmap.Height) Or (x < 0) Or (y < 0) Then
    Exit;
 
  FillColor2.red := (FillColor And $000000FF) Shl 8;
  FillColor2.green := (FillColor And $0000FF00);
  FillColor2.blue := (FillColor And $00FF0000) Shr 8;
 
  TempIntfImg := TLazIntfImage.Create(0, 0);
  TempIntfImg.LoadFromBitmap(Bitmap.Handle, Bitmap.MaskHandle);
  ReplaceColor := TempIntfImg.Colors[X, Y];
 
  If (ReplaceColor.red = FillColor2.red) And
    (ReplaceColor.green = FillColor2.green) And
    (ReplaceColor.blue = FillColor2.blue) Then
    Exit;
 
  stackp := -1;
 
  PutInStack(X, Y);
  While stackp >= 0 Do Begin
    GetFromStack(X, Y);
    While (X > 0) And ColorInRange(TempIntfImg.Colors[X - 1, Y], ReplaceColor) Do
      Dec(X);
    While (X < Bitmap.Width) And ColorInRange(TempIntfImg.Colors[X, Y], ReplaceColor) Do Begin
      If Y > 0 Then
        If ColorInRange(TempIntfImg.Colors[X, Y - 1], ReplaceColor) Then
          PutInStack(X, Y - 1);
      If Y + 1 < Bitmap.Height Then
        If ColorInRange(TempIntfImg.Colors[X, Y + 1], ReplaceColor) Then
          PutInStack(X, Y + 1);
      TempIntfImg.Colors[X, Y] := FillColor2;
      Inc(X);
    End;
  End;
 
  TempIntfImg.CreateBitmaps(ImgHandle, ImgMaskHandle, false);
  Bitmap.Handle := ImgHandle;
  Bitmap.MaskHandle := ImgMaskHandle;
  TempIntfImg.free;
  SetLength(Stack, 0);
 
End;
--
Just try it

Euklid
Lazarusforum e. V.
Beiträge: 2808
Registriert: Fr 22. Sep 2006, 10:38
OS, Lazarus, FPC: Lazarus v2.0.10, FPC 3.2.0
Wohnort: Hessen
Kontaktdaten:

Re: Floodfill für TBitmap

Beitrag von Euklid »

Hallo,

ich verwende immer dieses Floodfill, das nach meiner Erinnerung auch auf TBitmap angewandt werden kann...
http://www.lazarusforum.de/portal.php?c ... =floodfill" onclick="window.open(this.href);return false;

Viele Grüße, Euklid

Benutzeravatar
theo
Beiträge: 10871
Registriert: Mo 11. Sep 2006, 19:01

Re: Floodfill für TBitmap

Beitrag von theo »

Oder gleich OpBitmap verwenden?
Seit der letzten Version benötigt OpBitmap TLazIntfImage nicht mehr unbedingt.
D.h. es wird jetzt für Win, GTK2 und Qt direkt ans Widgetset gezeichnet.
Siehe lazbridge32. Das Ganze ist auch noch Alphakanal tauglich, was z.B. die LCL GTK2 noch nicht ist.

Benutzeravatar
corpsman
Lazarusforum e. V.
Beiträge: 1619
Registriert: Sa 28. Feb 2009, 08:54
OS, Lazarus, FPC: Linux Mint Mate, Lazarus GIT Head, FPC 3.0
CPU-Target: 64Bit
Wohnort: Stuttgart
Kontaktdaten:

Re: Floodfill für TBitmap

Beitrag von corpsman »

*g*

also unter gtk2 geht floodfill noch nicht,

das OpBitmap hab ich mir angesehen und es ist ja auch ganz nett.

Doch wenn ich alte Projekte nach Lazarus übersetzen lasse, will ich das mit so wenig wie möglich an Aufwand erledigen.

Für mich ist diese Umsetzung daher praktisch. Und gepostet habe ich es ja nur um anderen die Wahl zu lassen. Bzw, evtl. fühlt sich ja jemand heraus gefordert und optimiert noch ein bisschen was dran rum ;).
--
Just try it

Benutzeravatar
theo
Beiträge: 10871
Registriert: Mo 11. Sep 2006, 19:01

Re: Floodfill für TBitmap

Beitrag von theo »

corpsman hat geschrieben: Doch wenn ich alte Projekte nach Lazarus übersetzen lasse, will ich das mit so wenig wie möglich an Aufwand erledigen.
Ich auch, dafür habe ich mir OpBitmap geschrieben.
Was du da machst, ist alles andere als einfach.

Antworten