Zeichenprogramm: Fill

Status
Nicht offen für weitere Antworten.

Campino

Top Contributor
hi,

also: Ich versuche in Java ein Zeichen Programm ala Paint zu schreiben, allerdings macht mir die Fill-Funktion noch ärger. Unter "Fill" verstehe ich, dass man eine Farbfläche anklickt und die ganze Fläche mit einer Farbe "übermalt" wird.

Derzeit habe ich einen Algorithmus, der so aussieht:

Code:
/**Löst die Methode für den Point p (der wurde vom Nutzer angeklickt) im Graphics g 
     * (aus einem BufferedImage) aus. Setzt dabei 
     * als Farbe für p Color c vorraus.
     * @params Graphics g - Das Graphics des Bildes auf das gezeichnet wird
     * @param Raster r - Das Raster des Bildes
     * @param Point p - Der vom Nutzer angeklickte Punkt
     * @param Color c - aktuelle Farbe an p
     * @param Color fg - Vordergrundfarbe zum Zeichnen
     * @param Color bg - Hintergrundfarbe zum Zeichnen
     */
public void clicked(Graphics g, Raster r, Point p, Color c, Color fg,
            Color bg) {
        //Definitionen
        int px = (int) p.getX();
        int py = (int) p.getY();
        int data[] ;

        g.setColor(fg);
        g.fillRect(px, py, 0, 0); //P übermalen, der muss ja die Farbe der Fläche haben, Zeile 18

        Color a = c; //a ist also die Farbe, die übermalt werden soll.

        int pr = 0; //Zustand der Schleife, wird bis 7 hochgezählt um alle benachbarten Pixel zu haben
        Color b; //farbe der Nachbarpixel
        while (pr != 7) {
            try {
                //Wo sind wir gerade?
                switch (pr) {
                case 0:
                    data = new int[4];
                    data = r.getPixel(px + 1, py, data); //Farbwert des ersten Nachbarn auslesen
                    b = new Color(data[0], data[1], data[2], data[3]);
                    pr++; //Zustand hochzählen damit beim nächsten schleifendurchlauf das nächste 
                              //Nachbarpixel genommen wird
                    if (a.equals(b)) { //Vergleichen, Zeile 32
                        clicked(g, r, new Point(px + 1, py), a, fg, bg); //ggf. die methode für das Nachbarpixel aufrufen, 
                                                                                          //so als wäre auf dieses geklickt worden.
                    }
                    break;
                case 1: //Kommentare siehe case 0...
                    data = new int[4];
                    data = r.getPixel(px + 1, py + 1, data);
                    b = new Color(data[0], data[1], data[2], data[3]);
                    pr++;
                    if (a.equals(b)) { //Zeile 68
                        clicked(g, r, new Point(px + 1, py + 1), a, fg, bg);
                    }
                    break;
                case 2://Kommentare siehe case 0...
                    data = new int[4];
                    data = r.getPixel(px, py + 1, data);
                    b = new Color(data[0], data[1], data[2], data[3]);
                    pr++;
                    if (a.equals(b)) {
                        clicked(g, r, new Point(px, py + 1), a, fg, bg);
                    }
                    break;
                case 3://Kommentare siehe case 0...
                    data = new int[4];
                    data = r.getPixel(px - 1, py + 1, data);
                    b = new Color(data[0], data[1], data[2], data[3]);
                    pr++;
                    if (a.equals(b)) {
                        clicked(g, r, new Point(px - 1, py + 1), a, fg, bg);
                    }
                    break;
                case 4://Kommentare siehe case 0...
                    data = new int[4];
                    data = r.getPixel(px - 1, py, data);
                    b = new Color(data[0], data[1], data[2], data[3]);
                    pr++;
                    if (a.equals(b)) {
                        clicked(g, r, new Point(px - 1, py), a, fg, bg);
                    }
                    break;
                case 5://Kommentare siehe case 0...
                    data = new int[4];
                    data = r.getPixel(px - 1, py - 1, data);
                    b = new Color(data[0], data[1], data[2], data[3]);
                    pr++;
                    if (a.equals(b)) {
                        clicked(g, r, new Point(px - 1, py - 1), a, fg, bg);
                    }
                    break;
                case 6://Kommentare siehe case 0...
                    data = new int[4];
                    data = r.getPixel(px, py - 1, data);
                    b = new Color(data[0], data[1], data[2], data[3]);
                    pr++;
                    if (a.equals(b)) {
                        clicked(g, r, new Point(px, py - 1), a, fg, bg);
                    }
                    break;
                case 7://Kommentare siehe case 0...
                    data = new int[4];
                    data = r.getPixel(px + 1, py - 1, data);
                    b = new Color(data[0], data[1], data[2], data[3]);
                    pr++;
                    if (a.equals(b)) {
                        clicked(g, r, new Point(px + 1, py - 1), a, fg, bg);
                    }
                    break;
                }
            } catch (ArrayIndexOutOfBoundsException e) { //Die fliegt wenn wir versiuchen für ein Pixel zu arbeiten 
                                                                                 //das am Bildrand liegt, so dass das Nachbarpixel nicht 
                                                                                //auf dem Bild ist.
                pr++; //Wir machen einfach mit dem nächsten Nachbarn weiter, ein nichtvorhandener ist egal...
                continue;
            }
        }
    }

Leider fliegt eine StackOverflowException in den Zeilen 18, 32, 64 (im Code markiert). Hat jemand eine Idee wie ich das vermeiden kann? Oder weiß einen besseren Algorithmus?

Ich bedanke mich schonmal,
campino
 

Illuvatar

Top Contributor
Ich sehe da nix markiertes?
Aber egal, auf jeden Fall ist es, wenn ich das richtig sehen, ja so:
Du fängst bei einem Pixel an, und gehst alle umliegenden durch. D.h. im ersten rufst du rekursiv wieder die Methode auf. Da gehst du aber auch wieder alle umliegenden durch!Und es wird ja wohl nie so sein, dass ein Pixel keine umliegenden hat, also geht das immer weiter.
Kurz gesagt: Deine Rekursion hat keine Abbruchbedingung. Du rufst immer wieder dich selbst auf, ohne Ende... und nach ein paar zigtausend wenn nicht sogar paar Millionen mal gibt das ne Exception ;)
 

Campino

Top Contributor
Es geht ja nur weiter, wenn das Nachbarpixel die Farbe des Pixels hat. Weil das pixel aber bereits überzeichnet wurde, hat es dies4e garnicht mehr wenn es vom Nachbarn kontrolliert wird, oder?
 

Illuvatar

Top Contributor
Hmm und wie is das, stell dir mal vor, lauter schwarze Pixel, und zwei weiße nebeneinander, müsste der dann net immer hin- und herspringen?

Edit: ne wart mal ,das stimmt eigentlich was du gesagt hast :/
 
Status
Nicht offen für weitere Antworten.

Ähnliche Java Themen

Neue Themen


Oben