Floodfill für kleines Zeichenprogramm

paddy3k

Mitglied
Morgen :)

ich hab ein Problem und gestern auch schon den ganzen Tag nach einer Lösung gesucht.
Vielleicht gibts ja hier jemanden der mir helfen kann.

Ich suche einen Floodfill Algorithmus, so á la den Farbeimer in M$ Paint. Ich arbeite
in C++ und GDI+. Habe schon einige Algorithmen für C# gefunden aber leider kann
ich die nicht übernehmen :-/

Diesen Code hatte ich von Codeproject glaub ich, leider funktioniert er ned :

Code:
   void CChildView::floodFill(int x, int y)
   {
   	Color c1;
   	Color c2(255,255,255,255);   // Grenzfarbe weiß zum Test
   	
   	pic->GetPixel(x, y, &c1);	  // pic = Bitmap Typ
   
 	if(c1.GetRed() == c2.GetRed() && c1.GetGreen() == c2.GetGreen() && c1.GetBlue() == c2. GetBlue())
   	{
 		pic->SetPixel(x, y, Color(255,0,0,255)); 	// Fläche füllen, probeweise mit Blau
   		floodFill(x - 1, y);	// fill left 
   		floodFill(x + 1, y);	// fill right 
   		floodFill(x, y + 1);	// fill down 
   		floodFill(x, y - 1);	 // fill up
   	}
   }

Würde mich riesig freuen wenn mir da jemand helfen könnte !

Grüße
paddy
 
Hi,
was mich mal interessieren würde, was genau denn nicht? Malt er nicht oder gibt er eine Fehlermeldung ab?
 
Er stürzt mit einem Stack Overflow in der Funktion GetPixel dabei ab :(

edit:

Habe gerade herrausgefunden das der Absturz nur kommt wenn ich größere
Sachen füllen will. Zeichne ich ein kleines Rechteck, oder nen Kreis o.ä. geht es
und er füllt die Figur wie gewollt... hmmm
 
Zuletzt bearbeitet:
Rekursiv pixelweise ist ein bisschen happig für heutige Grafikgrössen, da machen die meisten nicht mit. Bei mehr als 20 Iterations-Tiefen (bzw. mehr bei weniger Stack-Variablen) sollte man den Algorithmus etwas umbauen.

Versuch, den Algorithmus mit einem Puffer der noch zu prüfenden Pixel umzubauen; vorzugsweise auch nicht einzelne Pixel, sondern horizontale Linien prüfen.
 
Zuletzt bearbeitet:
Hi,

leider habe ich keine Ahnung wie ich das umbauen soll :/ War froh das ich überhaupt was fertiges gefunden habe.

Ich probiere gerade eine andere Lösung, und zwar gibt es in der normalen GDI ja schon eine FloodFill Funktion. Hier mal mein Test Quelltext dazu :

Code:
  CPaintDC dc(this); 
  CDC memDC; 
  memDC.CreateCompatibleDC(&dc); 
   
  HBRUSH hbrush; 
  hbrush = CreateSolidBrush(RGB(255, 0, 255));    // Testfüllfarbe 
  SelectObject(memDC, hbrush);  
   
  COLORREF t = RGB(255, 255, 255);			// Testgrenzfarbe weiß 
  bool result = memDC.FloodFill(400, 250, t); 
   
  DeleteObject(hbrush); 
   
  dc.BitBlt(0, 0, x_size, y_size, &memDC, 0, 0, SRCCOPY);

Der Code wird problemlos ausgeführt und FloodFill gibt auch TRUE wieder was bedeutet das alles geklappt hat. Aber leider sehe ich auf dem Bildschirm nichts :/
 
Hast du auch irgendein Bild in memDC reingeladen? Das "überhaupt nix" sehen kann davon kommen dass in memDC auch nix ist.
Und noch was, bin mir nicht sicher aber FloodFill war was anderes als z.B. MSPaint das macht.
Versuch mal hiermit:
Code:
memDC.ExtFloodFill(400, 250, t, FLOODFILLSURFACE);
 
Zuletzt bearbeitet:
ich hab den memDC doch kompatible zum CPaintDC erstellt.
"Kopiert" er da nicht automatisch den Bildschirminhalt in den memDC ?

Hab auch mal das Floodflill weggelassen und nur ne Linie zeichnen wollen,
die hab ich auch ned gesehen.

Achso und ExtFloodFill hab ich auch schon ausprobiert. Das gleiche Problem.

edit : hab jetzt direkt nach CreateCompatibleDC die Zeile :

Code:
memDC.BitBlt(0, 0, 800, 600, &dc, 0, 0, SRCCOPY);

dc ist CPaintDC(this)
eingefügt. Aber geholfen hats irgendwie auch nichts *argh*
 
Zuletzt bearbeitet:
Ein DC ist keine Grafikoberfläche an sich. Eher eine Art Handle, die unter anderem auf einer Grafikfläche arbeiten kann. Wenn du einen DC erstellst, hat er kein zugewiesenes Arbeitsobjekt. Du müsstest ein CreateCompatibleBitmap machen, das dort rein SelectObjecten und dann kannst du BitBlt drauf machen.

Nicht vergessen, Bitmap auch wieder raus SelectObjecten und DeleteObjecten.
 
Ich habe schon damit rumprobiert. In den GDI+ gibt es eine Funktion die aus einem GDI+ Bitmap ein HBITMAP für GDI erzeugt.

Code:
HBITMAP hBitmap;
pic->GetHBITMAP(Color(255, 0, 0, 0), &hBitmap);

aber wie verwende ich das HBITMAP jetzt weiter ? SelectObject() akzeptiert es ja
so ned. Hm mal weiter probieren.
 
Tuhst du das jetzt doch in WinAPI proggen oder doch lieber MFC?
Also wenn wir bei MFC Bleiben.. Brauchst du HBITMAP doch garnicht
Ich bring mal alles zusammen:
Code:
CDC memDC; 
memDC.CreateCompatibleDC(&dc);
CBitmap pic;
pic.CreateCompatibleBitmap(&dc, width, height);
memDC.SelectObject(&pic); // Bruchst das WinAPI SelectObject garnicht.
memDC.BitBlt(... , &dc, ..., SRCCOPY);
memDC.ExtFloodFill(400, 250, t, FLOODFILLSURFACE);
dc.BitBlt(..., &memDC, ..., SRCCOPY);
// memDC und pic werden nach Benutzung umweltgerecht entsorgt ;)
 

Neue Beiträge

Zurück