AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Multimedia Delphi Füll-Werkzeug für Pixelprogramm
Thema durchsuchen
Ansicht
Themen-Optionen

Füll-Werkzeug für Pixelprogramm

Ein Thema von milos · begonnen am 2. Feb 2014 · letzter Beitrag vom 4. Feb 2014
Antwort Antwort
Namenloser

Registriert seit: 7. Jun 2006
Ort: Karlsruhe
3.724 Beiträge
 
FreePascal / Lazarus
 
#1

AW: Füll-Werkzeug für Pixelprogramm

  Alt 3. Feb 2014, 13:33
Wie soll das gehen?

Angenommen du fängst am roten Pixel an zu füllen. Wie willst du da "zeilenweise" alles ausfüllen?
Man muss sich ja nicht jedes einzelne Pixel merken.

Man füllt eine Zeile von links nach rechts, und gleichzeitig prüft man die Zeilen darüber und darunter. Für jeden gefundenen „Streifen“ legt man die Anfangsposition auf den Stack.

Anschließend wiederholt man das ganze für jeden Eintrag auf dem Stack, so lange, bis nichts neues mehr gefunden wird.
  Mit Zitat antworten Zitat
Medium

Registriert seit: 23. Jan 2008
3.689 Beiträge
 
Delphi 2007 Enterprise
 
#2

AW: Füll-Werkzeug für Pixelprogramm

  Alt 3. Feb 2014, 23:42
Zeilenweise "bulk"-füllen geht leider nur, wenn ein paar Bedingungen erfüllt oder genauere Umstände bekannt sind. Für den allgemeinen Fall ist rekursives Füllen nach wie vor aktuell bei Bitmaps, insbesondere weil es so einfach auch komplizierte Formen erledigen kann. (Mit Löchern und so Schweinerein z.B.)
"When one person suffers from a delusion, it is called insanity. When a million people suffer from a delusion, it is called religion." (Richard Dawkins)
  Mit Zitat antworten Zitat
Furtbichler
(Gast)

n/a Beiträge
 
#3

AW: Füll-Werkzeug für Pixelprogramm

  Alt 4. Feb 2014, 07:43
Die Idee vom FloodFill (aus dem Gedächtnis, Pseudocode):
Delphi-Quellcode:
procedure FloodFill (Bitmap,BackgroundColor,FillColor, X,Y)
begin
  if Bitmap.Inside(x,y) and Bitmap[x,y]=BackgroundColor then begin
    Bitmap[x,y] = FillColor;
    FloodFill(Bitmap, Backgroundcolor, FillColor, x-1 ,y);
    FloodFill(Bitmap, Backgroundcolor, FillColor, x+1 ,y);
    FloodFill(Bitmap, Backgroundcolor, FillColor, x ,y-1);
    FloodFill(Bitmap, Backgroundcolor, FillColor, x ,y+1);
 end;
end
Es ist so mit das ineffizienteste, was man machen kann, weswegen es die triviale Optimierung gibt, am Punkt (x,y) iterativ die ganze horizontale Linie nach links und nach rechts zu laufen, solange der Punkt in der Hintergrundfarbe ist. Dann wird FloodFill für den Punkte darüber und darunter aufgerufen (so ähnlich jedenfalls).

Wenn Du die Kanten des geschlossenen Polygons als Vektorliste hast, kannst Du nocht ausrechnen, welche Fläche 'innen' ist.

Wenn deine 8-Bit Grafiken aber nicht zu groß sind, reicht vermutlich der erste triviale Ansatz.
  Mit Zitat antworten Zitat
Medium

Registriert seit: 23. Jan 2008
3.689 Beiträge
 
Delphi 2007 Enterprise
 
#4

AW: Füll-Werkzeug für Pixelprogramm

  Alt 4. Feb 2014, 09:08
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.
"When one person suffers from a delusion, it is called insanity. When a million people suffer from a delusion, it is called religion." (Richard Dawkins)
  Mit Zitat antworten Zitat
Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#5

AW: Füll-Werkzeug für Pixelprogramm

  Alt 4. Feb 2014, 10:31
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 );
...
Delphi-Referenz durchsuchenTCanvas.FloodFill
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)
  Mit Zitat antworten Zitat
Bjoerk

Registriert seit: 28. Feb 2011
Ort: Mannheim
1.384 Beiträge
 
Delphi 10.4 Sydney
 
#6

AW: Füll-Werkzeug für Pixelprogramm

  Alt 4. Feb 2014, 12:36
Die Rekursion kann man vergessen (bringt regelmäßig Stackoverflow).

BTW, wie würde denn ein Algorithmus für fsBorder aussehen?

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;
  Mit Zitat antworten Zitat
Medium

Registriert seit: 23. Jan 2008
3.689 Beiträge
 
Delphi 2007 Enterprise
 
#7

AW: Füll-Werkzeug für Pixelprogramm

  Alt 4. Feb 2014, 13:13
Die Rekursion kann man vergessen (bringt regelmäßig Stackoverflow).
So pauschal stimmt das einfach nicht. Fläche klein genug oder Stack groß genug, und schon ist alles gut. (Ja, mit einem eigenen Stack ist man fast immer besser beraten, aber dennoch ist die Aussage faktisch falsch.)

Zitat:
BTW, wie würde denn ein Algorithmus für fsBorder aussehen?
Ich vermute du meinst die Unterscheidung zwischen "fülle diese einfarbige Fläche" und "fülle alles was von einem Rand mit Farbe X umgeben ist". Dann wäre "fsBorder":

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;
"When one person suffers from a delusion, it is called insanity. When a million people suffer from a delusion, it is called religion." (Richard Dawkins)
  Mit Zitat antworten Zitat
Blup

Registriert seit: 7. Aug 2008
Ort: Brandenburg
1.494 Beiträge
 
Delphi 12 Athens
 
#8

AW: Füll-Werkzeug für Pixelprogramm

  Alt 4. Feb 2014, 12:39
Gibt viele nette Sachen im Internet zu dem Thema mit Quellcode und Erklärung:
QuickFill-An-efficient-flood-fill-algorithm
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 00:35 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