Herzlich Willkommen, lieber Gast!
  Sie befinden sich hier:

  Forum » Java » weisse Flaeche in einem Bild fuellen

Forum | Hilfe | Team | Links | Impressum | > Suche < | Mitglieder | Registrieren | Einloggen
  Quicklinks: MSDN-Online || STL || clib Reference Grundlagen || Literatur || E-Books || Zubehör || > F.A.Q. < || Downloads   

Autor Thread - Seiten: > 1 <
000
05.02.2008, 22:30 Uhr
Meuterich



Nabend,

ich moechte in einem Bild (jpg || gif || png) eine weisse, durch
eine schwarze Linie umrandete, Flaeche mit einer anderen Farbe
fuellen lassen. Ich hab mir schon nen Wolf gesucht und find einfach
nix brauchbares. In der API find ICH nichts, was nicht heist, dass
es da nichts gibt ^^,

Kann mir da jemand einen weiterfuehrenden Tipp geben?

Meuterich

Hier mal so ein Bild zur Verdeutlichung:

--
Eine Signatur wird unter jedem von Ihnen erstellten Beitrag angefügt.
Maximal 5 Linien, jedoch nicht mehr als 600 Zeichen.
ThWboard-Code-Tags werden bis auf [url] und [img] nicht berücksichtigt.

Dieser Post wurde am 05.02.2008 um 22:31 Uhr von Meuterich editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
001
24.03.2008, 10:09 Uhr
~MartinF
Gast


Hallo,

ich bin zur Zeit dabei Java zu lernen (hab vor Jahren mit C und C++ angefangen). Also habe ich mich an die Aufgabe gewagt. Hier die Lösung:


C++:
package de.martin.fill;

import java.awt.Color;
import java.awt.Point;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;

public class FillApp {
    
    private BufferedImage image;

    public FillApp(File f) throws IOException {
        // Bild einlesen
        BufferedImage is = ImageIO.read(f);

        /*
         * is.setRGB(0, 0, Color.RED.getRGB()) würde eine
         * UnsupportedOperationException werfen. Weshalb?
         *
         * Wird das Bild zuerst kopiert, dann klappt alles. Geht das auch ohne
         * diesen Umweg?
         */


        // Hier wird das Bild kopiert
        final int w = is.getWidth();
        final int h = is.getHeight();
        image = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
        for (int x = 0; x < w; ++x)
            for (int y = 0; y < h; ++y)
                image.setRGB(x, y, is.getRGB(x, y));
    }

    /*
     * Sucht ein Pixel mit der Farbe color und einem benachbarten Pixel der
     * Farbe outline.
     */

    private Point findPixel(int color, int outline) {
        /*
         * Das ist nicht der schnellste Weg ... :)
         */

        for (int x = 0; x < image.getWidth(); ++x)
            for (int y = 0; y < image.getHeight(); ++y)
                if (image.getRGB(x, y) == color
                        && (image.getRGB(x + 1, y) == outline
                                || image.getRGB(x - 1, y) == outline
                                || image.getRGB(x, y + 1) == outline || image
                                .getRGB(x, y - 1) == outline))
                    return new Point(x, y);
        return null;
    }

    /*
     * Algorithmus zur Flutfüllung
     */

    public void start(int color, int outline, int newColor) {
        FloodfillAlgorithm proc = new FloodfillAlgorithm(image);

        Point p = findPixel(color, outline);
        while (p != null) {
            proc.start(p, newColor);
            p = findPixel(color, outline);
        }
    }

    /*
     * save speichert das bearbeitete Bild
     */

    public void save(File f) throws IOException {
        ImageIO.write(image, "png", f);
    }

    public static void main(String[] args) {
        try {
            // Die Pfade müssen angepasst werden !!
            FillApp app = new FillApp(new File("/home/martin/tmp/bild.gif"));
            app.start(Color.white.getRGB(), Color.black.getRGB(),
                    Color.red.getRGB());
            app.save(new File("/home/martin/tmp/out.png"));
            System.out.println("fertig");
        } catch (Exception e) {
            e.printStackTrace();
            System.exit(1);
        }
    }
}




C++:
package de.martin.fill;

import java.awt.Point;
import java.awt.image.BufferedImage;
import java.util.Stack;

public class FloodfillAlgorithm {
    private BufferedImage image;

    public FloodfillAlgorithm(BufferedImage image) {
        this.image = image;
    }

    public void start(Point p, int newColor) {
        int color = image.getRGB(p.x, p.y);

        Stack v = new Stack();
        v.push(p);

        while (!v.empty()) {
            p = (Point) v.pop();

            if (image.getRGB(p.x, p.y) == color) {
                image.setRGB(p.x, p.y, newColor);

                v.push(new Point(p.x, p.y + 1));
                v.push(new Point(p.x, p.y - 1));
                v.push(new Point(p.x + 1, p.y));
                v.push(new Point(p.x - 1, p.y));
            }
        }
    }

}



Der Algorithmus an sich ist nicht schwierig - im Netz finden sich genug Informationen.

Den Quelltext finde ich so noch nicht sehr schön. Es gibt einige Stellen, wo ich noch etwas verbessern würde aber leider nicht weiß wie (da fehlt mir noch das notwendige Verständnis von der umfangreichen Standardbibliothek). Vielleicht können die Java-Experten mal einen Blick drauf werfen? ...

Hoffe ich konnte weiterhelfen. Mir jedenfalls hat die Aufgabe viel gebracht. ;)

Grüße
Martin
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
Seiten: > 1 <     [ Java ]  


ThWBoard 2.73 FloSoft-Edition
© by Paul Baecher & Felix Gonschorek (www.thwboard.de)

Anpassungen des Forums
© by Flo-Soft (www.flo-soft.de)

Sie sind Besucher: