Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Multimedia (https://www.delphipraxis.net/16-multimedia/)
-   -   Delphi FloodFill Rekursiv (https://www.delphipraxis.net/94289-floodfill-rekursiv.html)

Neutral General 19. Jun 2007 12:45


FloodFill Rekursiv
 
Hi,

Ich benötige für mein Vorhaben eine FloodFill Procedure. Dazu hab ich erst mal eine "normale" programmiert.
Aber irgendwie bekomm ich dauernd nen Stack-Overflow... Wodran liegt denn das? Ich hab bei Wikipedia geguckt ob die das anders machen aber Wikipedia machts exakt genauso!

Delphi-Quellcode:
procedure FloodFill(ACanvas: TCanvas; x,y: Integer; AColor: TColor; Border: TColor);
begin
  if (ACanvas.Pixels[x,y] <> Border) then
  begin
    ACanvas.Pixels[x,y] := AColor;
    FloodFill(ACanvas,x+1,y,AColor,Border);
    FloodFill(ACanvas,x-1,y,AColor,Border);
    FloodFill(ACanvas,x,y+1,AColor,Border);
    FloodFill(ACanvas,x,y-1,AColor,Border);
  end;
end;
Gruß
Neutral General

nachti1505 19. Jun 2007 12:53

Re: FloodFill Rekursiv
 
Nur ne Vermutung, aber du hast nicht wirklich ne vernünftige Endbedingung, ausser wenn ALLES eingefärbt ist.

Will sagen, checke wenigstens mal ob 0<X<maxX und 0<Y<maxY.....

Neutral General 19. Jun 2007 12:56

Re: FloodFill Rekursiv
 
Ja das hatte ich mir auch schon gedacht aber ich hab die Fläche jetzt so eingegrenzt das sie nicht am Ende des Canvas ist sondern in der Mitte. Also ist die Abbruchbedingung auf jeden Fall erfüllt.. Wenn ich nur eine Richtung Rekursiv ausführe dann gehts.. Bei mehreren gibts nen Stack overflow.

Tormentor32 19. Jun 2007 12:59

Re: FloodFill Rekursiv
 
Delphi-Quellcode:
procedure FloodFill(ACanvas: TCanvas; x,y: Integer; AColor: TColor; Border: TColor);
begin
  if (ACanvas.Pixels[x,y] <> Border) then
  begin
    ACanvas.Pixels[x,y] := AColor;
    // Überprüfe vorm Aufruf erst, ob der Pixel die Bordercolor hat! Dann ruft er FloodFill nur auf, wenn nötig!
    FloodFill(ACanvas,x+1,y,AColor,Border);
    FloodFill(ACanvas,x-1,y,AColor,Border);
    FloodFill(ACanvas,x,y+1,AColor,Border);
    FloodFill(ACanvas,x,y-1,AColor,Border);
  end;
end;

nachti1505 19. Jun 2007 12:59

Re: FloodFill Rekursiv
 
So ganz macht deinen Code auch kein Sinn --->

bspw. wird Pixel 10,10 bearbeitet --> ist ungleich Border und wird auf Color gesetzt --> rek. Aufruf auf alle umliegenden Pixel --> der umliegende Pixel ruft ja wieder das Feld 10,10 auf.... der Vergleich ergibt true, da Border und AColor bestimmt unterschiedlich sind --> endlosschleife

Neutral General 19. Jun 2007 13:15

Re: FloodFill Rekursiv
 
Ok thx. Also ich habs jetzt so abgeändert:

Delphi-Quellcode:
procedure FloodFill(ABmp: TBitmap; x,y: Integer; AColor: TColor; Border: TColor);
begin
  if   (ABmp.Canvas.Pixels[x,y] <> Border) and (ABmp.Canvas.Pixels[x,y] <> AColor)
    and (x <= ABmp.Width) and (x >= 0) and (y <= ABmp.Height) and (y >= 0)
  then
  begin
    ABmp.Canvas.Pixels[x,y] := AColor;
    FloodFill(ABmp,x,y+1,AColor,Border);
    FloodFill(ABmp,x,y-1,AColor,Border);
    FloodFill(ABmp,x+1,y,AColor,Border);
    FloodFill(ABmp,x-1,y,AColor,Border);
  end;
end;
Das klappt auch bei manchen flächen.. Aber bei Flächen die viel Bitmap-Rand enthalten gibts wieder en Stack-Overflow... -.-

Gruß
Neutral General

dizzy 19. Jun 2007 13:20

Re: FloodFill Rekursiv
 
Zitat:

Zitat von Neutral General
Delphi-Quellcode:
(x <= ABmp.Width) and (y <= ABmp.Height)

Ein Bitmap geht von x: 0..Width-1; y: 0..Height-1. Könnte evtl. die Ursache sein. Typisches off-by-one ;)

Hawkeye219 19. Jun 2007 13:26

Re: FloodFill Rekursiv
 
Hallo,

eine Frage: was spricht gegen die Verwendung von Delphi-Referenz durchsuchenTCanvas.FloodFill?

Gruß Hawkeye

Neutral General 19. Jun 2007 13:27

Re: FloodFill Rekursiv
 
Zitat:

Zitat von dizzy
Zitat:

Zitat von Neutral General
Delphi-Quellcode:
(x <= ABmp.Width) and (y <= ABmp.Height)

Ein Bitmap geht von x: 0..Width-1; y: 0..Height-1. Könnte evtl. die Ursache sein. Typisches off-by-one ;)

Wie war das mit dem Wald den man vor lauter Bäumen nicht mehr sieht ? :mrgreen: :wall:

Danke :)

Gruß
Neutral General

gammatester 19. Jun 2007 13:29

Re: FloodFill Rekursiv
 
Zitat:

Zitat von dizzy
Zitat:

Zitat von Neutral General
Delphi-Quellcode:
(x <= ABmp.Width) and (y <= ABmp.Height)

Ein Bitmap geht von x: 0..Width-1; y: 0..Height-1. Könnte evtl. die Ursache sein. Typisches off-by-one ;)

Außerdem zuerst die Bereiche testen und dann die Farben, sonst könnte es, wenn's dumm läuft, statt des Stackfehlers einen Zugriffsfehler geben.

Gammatester


Alle Zeitangaben in WEZ +1. Es ist jetzt 21:25 Uhr.
Seite 1 von 2  1 2      

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz