Inselraus: Swing/AWT-Bilder im Speicher erzeugen

Nicht immer kommen die Bilder vom Datensystem oder aus dem Internet. Mit der Java-Bibliothek lassen sich einfach auch eigene (Buffered)Image-Objekte anlegen. Dazu bieten sich – wieder historisch bedingt – verschiedene Varianten an:

  • Jede AWT-Komponente, wie Frame oder Panel, bietet die Methode createImage(…). Die Anweisung Image image = panel.createImage(800, 600); erzeugt ein Image-Objekt mit 800 Pixeln in der Breite und 600 in der Höhe, das mit getGraphics() Zugriff auf den Grafikkontext bietet. Wenn die AWT-Komponente noch nicht angezeigt wurde, liefert createImage(…) die Rückgabe null, sodass hier leicht eine NullPointerException entstehen kann. Auch unterstützen die Bilder keine Transparenz.
  • Java 1.2 führte die Klasse BufferedImage ein, die eine Erweiterung der Image-Klasse ist. Image ist eine abstrakte Klasse und BufferedImage eine konkrete nicht abstrakte Unterklasse. Ein zentraler Unterschied ist, dass der Zugriff auf die Pixel von BufferedImage-Objekten einfach ist, weil sie auf der Java-Seite in Byte-Arrays gespeichert sind, dass aber der Zugriff auf die Pixel von Image-Objekten schwierig ist, da Image-Objekte vom Betriebssystem kommen. Bei BufferedImage ist die Manipulation der Pixel einfach. Die Klasse bietet drei Konstruktoren. Beim Erzeugen ist immer ein Bildtyp anzugeben, der über die physikalische Speicherung bestimmt.[1]
  • createCompatibleImage(…) über GraphicsConfiguration erzeugt ein BufferedImage und benötigt keinen Bildtyp.
BufferedImage erzeugen lassen

Ein Bild über createCompatibleImage(…) zu erzeugen, hat den großen Vorteil, dass das Daten- und Farbmodell optimal gewählt ist. Der einzige Nachteil dieser Methode ist die große Menge an benötigten Hilfsobjekten – was zusätzliche Schreibarbeit bedeutet:

GraphicsConfiguration gfxConf = GraphicsEnvironment.getLocalGraphicsEnvironment().
    getDefaultScreenDevice().getDefaultConfiguration();
int width = 600, height = 400;
BufferedImage image = gfxConf.createCompatibleImage( width, height );

Neben createCompatibleImage(int, int) gibt es auch eine Variante, die die Angabe einer Transparenz ermöglicht.

abstract class java.awt.GraphicsConfiguration

  • abstract BufferedImage createCompatibleImage(int width, int height)
    Erzeugt ein BufferedImage.
  • BufferedImage createCompatibleImage(int width, int height, int transparency)
    Erzeugt ein BufferedImage mit optionaler Transparenz. Das Argument für transparency kann sein: Transparency.OPAQUE (keine Transparenz, der Alpha-Wert ist 1,0), Transparency.BITMASK (Bilddaten sind komplett sichtbar, also opak mit Alpha-Wert 1, oder transparent, also Alpha-Wert 0), Transparency.TRANSLUCENT (Grafik erlaubt das Durchscheinen mit Alpha-Werten von 0,0 bis 1,0).
Das Bild bemalen

Image-Objekte (BufferedImage ist eine Unterklasse) geben über getGraphics() das Graphics-Objekt zurück, mit dem sich das Bild bemalen lässt. Im Fall eines speziellen BufferedImage-Objekts ist es jedoch üblich, die Methode createGraphics() einzusetzen, da sie ein Graphics2D-Objekt – eine Unterklasse von Graphics – liefert, mit dem weitere Zeichenoperationen möglich sind. Außerdem ruft getGraphics() sowieso createGraphics() auf …

Beispiel: Initialisiere ein Bild img mit weiß.

Graphics2D g = img.createGraphics();
g.setColor( Color.WHITE );
g.fillRect( 0, 0, b – 1, h – 1 );

Alternativ kann zum Löschen des Hintergrunds auch g.setBackground(Color.WHITE); g.clearRect(…); verwendet werden.

BufferedImage von Hand erzeugen

Der Konstruktor der Klasse BufferedImage wird mit den Maßen parametrisiert und zusätzlich mit einem Speichermodell für die Bildinformationen. Das ermöglicht die Verwendung von beliebigen Farb- und Speichermodellen:

int h = 400,
    b = 600;
BufferedImage img = new BufferedImage( b, h, BufferedImage.TYPE_INT_RGB );

Das notwendige dritte Argument kennzeichnet den Speichertyp; hier sind die Farben durch je 8 Bit Rot, Grün und Blau abgebildet. Um weitere 2 der über 10 Bildtypen zu nennen: TYPE_USHORT_GRAY (Graubilder) oder TYPE_INT_ARGB (RGB mit jeweils 8 Bit sowie Alpha).

class java.awt.image.BufferedImage
extends Image
implements RenderedImage, Transparency, WritableRenderedImage

  • BufferedImage(int width, int height, int imageType)
    Liefert ein neues Hintergrundbild mit den gegebenen Maßen.

[1] Details finden Sie unter http://weblogs.java.net/blog/chet/archive/2004/08/toolkitbuffered.html.

Über Christian Ullenboom

Ich bin Christian Ullenboom und Autor der Bücher ›Java ist auch eine Insel. Einführung, Ausbildung, Praxis‹ und ›Java SE 8 Standard-Bibliothek. Das Handbuch für Java-Entwickler‹. Seit 1997 berate ich Unternehmen im Einsatz von Java. Sun ernannte mich 2005 zum ›Java-Champion‹.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.