# Anzeigen von fotos: ImageIcon oder BufferedImage + paint() ?



## lupylucke (15. Apr 2007)

Hallo!

Ich hab da eine "grundlegende" Frage zu Bilder in Java. Das Programm, das ich entwickle, soll eine reihe ziemlich grosser Bilder anzeigen (nein, ich schreibe *kein* Programm zum Anzeigen/verwalten von Fotos, davon gibt's schon genug...)
Nach dem, was ich bisher gelesen habe scheint es zwei Methoden zu geben, ein Bild oder ein Foto in die GUI zu bringen:
1) mit ImageIcon + z.b. ein JLabel. 
2) mit BufferedImage, ein JPanel oder Canvas und deren paint() methode

So weit ich verstanden habe, hat 2) den Vorteil, dass man das Bild editieren kann, zum Beispiel etwas drauf zeichnen. Das brauche ich aber nicht. 
Meine Frage: welche ist in meinem Fall "besser"? Vor allem: gibt es Unterschiede bezüglich Speicherbedarf und Performance? 

Danke im Voraus


----------



## Wildcard (15. Apr 2007)

lupylucke hat gesagt.:
			
		

> Meine Frage: welche ist in meinem Fall "besser"? Vor allem: gibt es Unterschiede bezüglich Speicherbedarf und Performance?


Nicht wirklich, egal wie du's machst wird ein großes Bild eine Menge Speicher fressen.
Dir muss klar sein das das Bild dekomprimiert werden muss, also um ein vielfaches Größer als ein jpg/png wird.
ob du nun ein ImageIcon oder ein BufferedImage nimmst ändert daran nichts.


----------



## abollm (16. Apr 2007)

Noch einmal ergänzend zu dem was Wildcard geschrieben hat:

Für den Speicherbedarf ist das Bildformat ausschlaggebend. Für die Geschwindigkeit des Ladens von sehr großen Bildern ist ggf. eine Wandelroutine von kompimiert zu dekomprimiert sinnvoll (BMP wirst du wohl kaum speichern). Das Problem dabei ist nur die Frage nach dem Verlustfaktor hinsichtlich Anzeigen des Bildes.

Für das Thema des Zugriffs aber noch ein Hinweis direkt von Sun:

"The ImageInputStream is an interface of the javax.imageio.stream package that is seekable, and so it's potentially faster than a regular InputStream. Instead of getting an InputStream from a FileInputStream, and passing that InputStream into the read method, it's more efficient to pass the File object to be read, or to create a FileImageInputStream from the File. More specifically, instead of

```
InputStream is = new InputStream("anImage.jpg");
ImageIO.read(is);
```
use either:

```
File file = new File("anImage.jpg");
ImageIO.read(file);
```
or

```
File file = new File("anImage.jpg");
FileImageInputStream fiis = new FileImageInputStream(file);
ImageIO.read(fiis);
```
The read method (in all cases) returns a BufferedImage object. You can then draw this image with the drawImage method of Graphics, or you can filter it with something ...  from the java.awt.image package."

Hth


----------



## Ullenboom (16. Apr 2007)

Also wenn es wirklich seeehr große Bilder sind, dann lohnt sich vielleicht ein Blick auf die Super-Sonder-Spezial-Bilder-API  (Java Advanced Imaging). Interessante Links sind

http://java.sun.com/javase/technologies/desktop/media/jai/
https://jai-imageio.dev.java.net/
https://jai.dev.java.net/


----------



## lupylucke (18. Apr 2007)

Zuerst mal danke für eure Antworten!

Wenn man die falsche Frage stellt muss man sich nicht wundern, wenn man nicht passende Antworten bekommt  :wink:  Ich war wohl nich mehr ganz klar im Kopf als ich mein Post schrieb, war auch schon ziemlich spät...

Also, eigentlich wollte ich allgemein wissen was die Unterschiede zwischen ImageIcon und BufferedImage sind. Gibt es überhaupt welche? Wann sollte man das eine, wann das andere Vorgehen anwenden, um ein Bild anzuzeigen? 

Vergesst bitte den Teil über Performance und Speicherbedarf, dass das von anderen Dingen abhängt war mir eigentlich klar.

Danke!

PS  Danke Ullenboom für deine Links, werd's mal anschauen. Allerdings sind meine Bilder auch nich wieder soooooo gross...


----------



## Ullenboom (18. Apr 2007)

Schau mal in den Programmcode von ImageIcon. Da ist gut zu sehen, dass der MediaTracker dahinter steckt, der das Image lädt.


```
transient Image image;

    /**
     * Creates an ImageIcon from the specified URL. The image will
     * be preloaded by using MediaTracker to monitor the loaded state
     * of the image.
     * @param location the URL for the image
     * @param description a brief textual description of the image
     * @see #ImageIcon(String)
     */
    public ImageIcon(URL location, String description) {
	image = Toolkit.getDefaultToolkit().getImage(location);
        if (image == null) {
            return;
        } 
	this.location = location; 
        this.description = description;
	loadImage(image);
    }
```

Der wiederum erzeugt das Image-Objekt, was beim Zeichen verwendet wird.


```
public synchronized void paintIcon(Component c, Graphics g, int x, int y) {
        if(imageObserver == null) {
           g.drawImage(image, x, y, c);
        } else {
	   g.drawImage(image, x, y, imageObserver);
        }
    }
```

Ob das Image auch ein BufferedImage ist (ist ja eine Unterklasse von Image) kann sein, muss aber nicht auf jeder Plattform zwingend gelten.[/code]


----------

