![]() |
AW: Füll-Werkzeug für Pixelprogramm
Da es hier ja um einen Bildeditor geht, nicht um Animationen bei denen jedes Frame etwas neu gefüllt werden muss, wird der triviale Ansatz locker reichen. Man sollte nur überlegen, ob man nicht lieber mit Scanline statt Pixels[] da dran geht (vorausgesetzt man arbeitet mit einem TBitmap, was hier glaube ich nichtmals der Fall ist).
Ohne die Zeilen-Optimierung muss man ggf. nur aufpassen, dass man ab gewissen Bildgrößen keinen Stacküberlauf bekommt. Da ginge im Zweifel als Lösung auch noch die iterative Variante mit selbst verwaltetem Stapel. |
AW: Füll-Werkzeug für Pixelprogramm
Wie wäre es denn mit dieser Funktion?
Delphi-Quellcode:
procedure FloodFill( Canvas : TCanvas; x, y : Integer; NewColor : TColor );
var LCurrentColor : TColor; begin Canvas.Brush.Color := NewColor; Canvas.Brush.Style := bsSolid; LCurrentColor := Canvas.Pixels[x, y]; Canvas.FloodFill( x, y, LCurrentColor, fsSurface ); end; ... FloodFill( MyBitmap.Canvas, 23, 54, clRed ); ... ![]() |
AW: Füll-Werkzeug für Pixelprogramm
Die Rekursion kann man vergessen (bringt regelmäßig Stackoverflow).
BTW, wie würde denn ein Algorithmus für fsBorder aussehen? :gruebel: fsSurface ist ja dieser:
Delphi-Quellcode:
procedure TFloodFill.FloodFill4(X, Y: integer);
var P: TPoint; Stack: TPointStack; begin Stack := TPointStack.Create; try Stack.Push(Point(X, Y)); while not Stack.Empty do begin P := Stack.Pop; if IsCurrentColor(P.X, P.Y) then // OldColor; begin FPixels[P.X, P.Y] := FBrushColor; // NewColor; Stack.Push(Point(P.X, P.Y + 1)); Stack.Push(Point(P.X, P.Y - 1)); Stack.Push(Point(P.X + 1, P.Y)); Stack.Push(Point(P.X - 1, P.Y)); end; end; finally Stack.Free; end; end; |
AW: Füll-Werkzeug für Pixelprogramm
Gibt viele nette Sachen im Internet zu dem Thema mit Quellcode und Erklärung:
![]() |
AW: Füll-Werkzeug für Pixelprogramm
Zitat:
Zitat:
Delphi-Quellcode:
procedure TFloodFill.FloodFill4(X, Y: integer);
var P: TPoint; Stack: TPointStack; begin Stack := TPointStack.Create; try Stack.Push(Point(X, Y)); while not Stack.Empty do begin P := Stack.Pop; if not IsBorderColor(P.X, P.Y) then begin FPixels[P.X, P.Y] := FBrushColor; Stack.Push(Point(P.X, P.Y + 1)); Stack.Push(Point(P.X, P.Y - 1)); Stack.Push(Point(P.X + 1, P.Y)); Stack.Push(Point(P.X - 1, P.Y)); end; end; finally Stack.Free; end; end; |
AW: Füll-Werkzeug für Pixelprogramm
Liste der Anhänge anzeigen (Anzahl: 1)
Ich hab gestern meinen alten Labyrinth Code ausgepackt und die Entstehung visualisiert, da ich selbst sehen wollte was da vor sich geht. Es ist ja nicht das Fill Problem, aber ich denke es ist im Grunde ein ähnliches Problem, da sich auch bei Fill die Wege oft trennen. Dabei habe ich auch den Stack visualisiert (rote Punkte), und war letztendlich selbst überrascht, wie viele Werte es dann doch sind. Ist aber auch richtig, denn bei dem Drang nach vorne wird immer dann eine Position auf Stack gelegt, wenn es zu dem Zeitpunkt mehr als eine Möglichkeit gab. Einiges erledigt sich im Laufe der weiteren Berechnung, aber jede Punkt wird noch mal besucht und kontrolliert.
Das Beispiel zeigt eine verzögerte Berechnung eines Labyrinths und wo überall und wie viele Werte auf Stack gelegt wurde. Interessant zu sehen, falls man den Stack bei der Arbeit zusehen möchte. |
AW: Füll-Werkzeug für Pixelprogramm
Ok. Logo. Thanx @ Medium. Bin allerdings schon der Auffassung, daß das hier der Klassiker für einen Stack ist? Hatte gestern Tests mit 200 x 200 Pixel Fläche durchgeführt. Kam bei jedem 3. Durchlauf ein Stackoverflow? Den Stack hochstellen hab ich noch nie gemacht?
|
AW: Füll-Werkzeug für Pixelprogramm
Zitat:
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 03:51 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz