| Axel Rogat |
| Objektorientiertes Programmieren mit C++ und JAVA |
|   |
30.4: Font
| Kapitel 30 |
31: Das AWT 
|
|   |
|   | 30.5 Image |   |
|   |
Es gibt eine Vielzahl ausgefeilter Möglichkeiten, fertige Bilder in ein Applet einzubauen -- beispielsweise stückweise, während sie noch über das Netz geladen werden, während eine Kamera sie übermittelt, etc. Wir werden uns zunächst nur mit einfachen Versionen begnügen.
Die Property awt.image.redrawrate legt fest, wie oft das geschieht. Sie ist normalerweise auf 0.1 Sekunden eingestellt. Setzt man die Property awt.image.incrementaldraw auf false, wird der Observer erst ganz zum Schluß benachrichtigt.
Image-Zeichenfunktionen in Graphics
| boolean drawImage(Image, int x, int y, ImageObserver)
|  
| Bild zeichnen
|
boolean drawImage(Image, int x, int y, intwidth, int height, ImageObserver)
|  
| Bild zeichnen, angepaßt auf die angegebene Breite/Höhe
|
boolean drawImage(Image, int x, int y, Color bgcolor, ImageObserver)
|  
| Bild zeichnen, noch ungeladene Teile mit bgcolor ausfüllen
|
boolean drawImage(Image, int x, int y, int width, int height, Color bgcolor, ImageObserver)
|  
| Bild zeichnen, angepaßt und mit bgcolor aufgefüllt
| boolean drawImage(Image, int dx1, int dy1, int dx2, int dy2, int sx1, int sy1, int sx2, int sy2, ImageObserver)
|  
| Bildausschnitt (sx1,sy1)-(sx2,sy2) angepaßt in das Rechteck (dx1,dy1)-(dx2,dy2) zeichnen
|
boolean drawImage(Image, int dx1, int dy1, int dx2, int dy2, int sx1, int sy1, int sx2, int sy2, Color bgColor, ImageObserver)
|  
| wie oben, ungeladene Teile mit bgcolor füllen
| | |||||||
Beispiel: Das folgende kurze Applet lädt ein Bild namens "image.gif" als Resource (aus einem .jar-File oder aus dem gleichen Verzeichnis wie den Applet-Code). Während des Ladevorgangs wird das Bild in Originalgröße in die obere linke Ecke des Applet-Bereichs gemalt. Sobald es fertig geladen ist, wird es immer der Größe des Applet-Bereichs angepaßt -- also auch beim Ändern der Größe des Appletviewers:
Memberfunktionen von Image
| int getWidth(ImageObserver)
|  
| Breite in Pixeln (-1, solange unbekannt)
| int getHeight(ImageObserver)
|  
| Höhe in Pixeln (-1, solange unbekannt)
| ImageProducer getSource()
|  
| Urheber des Bildes
| Graphics getGraphics()
|  
| GC für Hintergrund-Bilder
| Object getProperty(String,ImageObserver)
|  
| Property lesen
| Image getScaledInstance(int height, int width, int hints)
|  
| skalierte Kopie anlegen (s.u.)
| void flush()
|  
| alle benötigten Ressourcen freigeben
| | ||||||||
Wenn das Bild nicht nur gestreckt/gestaucht gezeichnet, sondern auch so abgespeichert werden soll, kann man mit getScaledInstance eine verzerrte Kopie anlegen. Man kann als letzten Parameter angeben, wie die Größenanpassung vor sich gehen soll:
Image-Skalierungsverfahren
| SCALE_DEFAULT
| voreingestellt (z.B. im Appletviewer)
| SCALE_AREA_AVERAGING
| Durchschnitt über Pixel-Cluster verwenden
| SCALE_SMOOTH
| das Verfahren mit der höchsten Qualität
| SCALE_FAST
| das schnellste Verfahren
| SCALE_REPLICATE
| Zeilen/Spalten werden einfach wiederholt
| | |
Beispiel: Zunächst schreiben wir ein Applet, das mit einem Thread arbeitet, um eine Animation darzustellen. Unsere Klasse erbt also von Applet und implementiert das Interface Runnable. In der Methode run warten wir einige Millisekunden, berechnen dann das nächste Bild und rufen repaint auf (was letzlich paint aufrufen wird).
Wir stellen einen kleinen blauen Ball (ein einfarbiger Kreis) dar, der im Applet herumfliegt und an den Rändern abprallt. Die Berechnungen für den Abprall-Vorgang sind dabei stark vereinfacht worden, da sie hier nicht im Mittelpunkt stehen. Damit der Hintergrund nicht langweilig weiß bleibt, zeichnen wir dorthin jeweils zwei große farbige Rechtecke.
Beispiel: Wir verbessern unser Applet, indem wir mit 3 nicht direkt sichtbaren Bereichen arbeiten:
Wenn sich die Größe des Applets ändert, passen wir den ersten und dritten Bereich der neuen Dimension an. Die Hintergrundgrafik wird dann auch neu gemalt.
Wir verwenden anstatt dessen einen speziellen ImageProducer aus java.awt.image namens MemoryImageSource. Wir legen ein Array pixels von einem int für jeden Pixel an und füllen dieses zunächst mit unseren berechneten Werten. Die nicht zum Ball gehörenden Werte (der Rand) werden nicht beschrieben und bleiben 0, sind also komplett durchsichtig. Die anderen Werte werden nach dem Muster 0xffrrggbb berechnet, ff für vollständig undurchsichtig, dann 8 Bit pro Komponente Rot, Grün, Blau.
Der ImageProducer erhält im Konstruktor Breite und Höhe des Bilds, das er produzieren soll, das Array mit den Pixel-Werten, die Nummer des ersten Pixels im Array (0 bei uns) und die Breite der Scan-Line im Array (bei uns gleich der Breite des Image).
Mit einem Aufruf der folgenden Art erhält man dann das gewünschte Bild:
Ein Test-HTML-Dokument ist folgendes:
Der Quelltext unseres Applets folgt. |
|
|   |
30.4: Font
| Startseite |
31: Das AWT 
|
|   |