java.awt.Toolkit.getDefaultToolkit() | Liefert das standardmäßige grafische Toolkit. |
beep() | Piepston. |
getImage() | Lade Bild. |
getSystemClipboard() | Zwischenablage. |
getScreenSize() | Bildschirmauflösung. |
getColorModel().getPixelSize() | Bits pro Pixel. |
getLocalGraphicsEnvironment() getScreenDevices() getConfigurations() java.awt.GraphicsConfiguration |
Ab JDK 1.3 sind weitere Informationen per
GraphicsConfiguration verfügbar. Insbesondere bei mehreren angeschlossenen Bildschirmen können nur hierüber korrekte Informationen bezogen werden. |
import java.applet.Applet; import java.awt.*; public class MyAwtApplet extends Applet { public void paint( Graphics g ) { int iWidth = getSize().width; int iHeight = getSize().height; g.setColor( Color.blue ); g.drawRoundRect( 0, 0, iWidth-1, iHeight-1, 16, 16 ); g.setColor( Color.black ); FontMetrics fm = g.getFontMetrics( g.getFont() ); String s = "" + iWidth + " x " + iHeight + " Pixel"; g.drawString( s, (iWidth - fm.stringWidth(s))/2, (iHeight - fm.getHeight())/2 + fm.getAscent() ); } }Folgenden Text in Datei MyAwtApplet.html speichern:
<html><body> <h3>Ausgabe eines Java-Applets:</h3> <applet code="MyAwtApplet.class" width=250 height=80> <br>Bitte Java-Support einschalten !<br> </applet> </body></html>Java-Applet compilieren und ansehen mit:
javac MyAwtApplet.java
appletviewer MyAwtApplet.html
Falls das Applet mit JDK 1.1 compiliert wurde, kann die HTML-Seite auch in übliche Web-Browser geladen werden.import java.awt.*; import java.awt.event.*; public class MyAwtFrame extends Frame { public static void main( String[] args ) { MyAwtFrame frm = new MyAwtFrame(); frm.setTitle( "My AWT Frame" ); frm.setSize( 400, 300 ); frm.setVisible( true ); } public MyAwtFrame() { addWindowListener( new WindowAdapter() { public void windowClosing( WindowEvent ev ) { dispose(); System.exit( 0 ); } } ); } public void paint( Graphics g ) { Insets insts = getInsets(); int iOriginX = insts.left; int iOriginY = insts.top; int iSizeX = getSize().width - insts.left - insts.right; int iSizeY = getSize().height - insts.top - insts.bottom; g.setColor( Color.blue ); g.drawRoundRect( iOriginX, iOriginY, iSizeX-1, iSizeY-1, 16, 16 ); g.setColor( Color.black ); FontMetrics fm = g.getFontMetrics( g.getFont() ); String s = "" + iSizeX + " x " + iSizeY + " Pixel"; g.drawString( s, (iSizeX - fm.stringWidth(s))/2, (iSizeY - fm.getHeight())/2 + fm.getAscent() ); } }
import java.awt.*; public class ImgShowComponent extends Canvas { private Image img = null; ImgShowComponent( String sFile ) { img = getToolkit().getImage( sFile ); MediaTracker mt = new MediaTracker( this ); mt.addImage( img, 0 ); try { mt.waitForAll(); } catch( InterruptedException ex ) { } } public void paint( Graphics g ) { g.drawImage( img, 0, 0, this ); } public Dimension getPreferredSize() { return new Dimension( img.getWidth( this ), img.getHeight( this ) ); } public Dimension getMinimumSize() { return getPreferredSize(); } }MyImgShow demonstriert, wie obige ImgShowComponent-Komponente in eine Applikation eingebunden wird.
import java.awt.*; import java.awt.event.*; public class MyImgShow extends Frame { public static void main( String[] args ) { if( 1 > args.length ) System.out.println( "Usage:\njava MyImgShow <ImgFile>\nE.g.:\njava MyImgShow x.png" ); else new MyImgShow( args[0] ); } MyImgShow( String sFile ) { super( sFile ); setSize( 100, 100 ); setVisible( true ); add( new ImgShowComponent( sFile ) ); pack(); addWindowListener( new WindowAdapter() { public void windowClosing( WindowEvent ev ) { dispose(); System.exit( 0 ); } } ); } }
import java.awt.*; import java.awt.geom.AffineTransform; public class ImgRotateComponent extends Canvas { private Image img; private double dDegrees; private int iDegrees, iSizeDiff, iSizeMax; ImgRotateComponent( String sFile, double dDegrees ) { this.dDegrees = dDegrees; iDegrees = (int)Math.round( dDegrees ); while( 0 > iDegrees ) iDegrees += 360; iDegrees %= 360; img = getToolkit().getImage( sFile ); MediaTracker mt = new MediaTracker( this ); mt.addImage( img, 0 ); try { mt.waitForAll(); } catch( InterruptedException ex ) { } iSizeDiff = img.getWidth(this) - img.getHeight(this); iSizeMax = Math.max( img.getWidth(this), img.getHeight(this) ); } public void paint( Graphics g ) { Graphics2D g2 = (Graphics2D)g; g2.setRenderingHint( RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON ); AffineTransform at = AffineTransform.getRotateInstance( dDegrees * Math.PI/180., (iSizeMax+1)/2, (iSizeMax+1)/2 ); g2.setTransform( at ); int iMoveX=0, iMoveY=0; if( 0 < iSizeDiff && ( 90 == iDegrees || 180 == iDegrees ) ) iMoveY = iSizeDiff; if( 0 > iSizeDiff && ( 180 == iDegrees || 270 == iDegrees ) ) iMoveX = -iSizeDiff; g2.drawImage( img, iMoveX, iMoveY, this ); } public Dimension getPreferredSize() { int iSizeX = iSizeMax; int iSizeY = iSizeMax; if( 0 == iDegrees || 180 == iDegrees ) if( 0 < iSizeDiff ) iSizeY = img.getHeight(this); else if( 0 > iSizeDiff ) iSizeX = img.getWidth(this); if( 90 == iDegrees || 270 == iDegrees ) if( 0 < iSizeDiff ) iSizeX = img.getHeight(this); else if( 0 > iSizeDiff ) iSizeY = img.getWidth(this); return new Dimension( iSizeX, iSizeY ); } public Dimension getMinimumSize() { return getPreferredSize(); } }MyImgRotate demonstriert, wie obige ImgRotateComponent-Komponente in eine Applikation eingebunden wird.
import java.awt.*; import java.awt.event.*; public class MyImgRotate extends Frame { public static void main( String[] args ) { if( 2 > args.length ) System.out.println( "Usage:\njava MyImgRotate <ImgFile> <degrees>\nE.g.:\njava MyImgRotate x.png -90" ); else new MyImgRotate( args[0], args[1] ); } MyImgRotate( String sFile, String sDegrees ) { super( sFile ); setSize( 100, 100 ); setVisible( true ); add( new ImgRotateComponent( sFile, Double.parseDouble( sDegrees ) ) ); pack(); addWindowListener( new WindowAdapter() { public void windowClosing( WindowEvent ev ) { dispose(); System.exit( 0 ); } } ); } }
Die Klasse MyImgStore dient zur Demonstration der Verwendung der vier im folgenden vorgestellten abstrakten Klassen ImgImageIoStore, ImgJpegStore, ImgJimiStore und ImgPaintStore. Sie muss dafür jeweils an den drei mit "// adapt: ..." gekennzeichneten Stellen angepasst werden.
In myPaintFunction() wird das zu speichernde Bild erzeugt und mit store() wird es gespeichert.
import java.awt.*; public class MyImgStore extends ImgImageIoStore // adapt: ImgImageIoStore | ImgJpegStore | ImgJimiStore | ImgPaintStore { public static void main( String[] args ) { try { MyImgStore mis = new MyImgStore(); mis.store( 400, 300, "x.png" ); // adapt: store | paintAndStore and "x.png" | "x.jpg" } catch( Exception ex ) { System.out.println( ex.getMessage() ); System.exit( 1 ); } System.out.println( "Image stored." ); System.exit( 0 ); } public void myPaintFunction( Graphics2D g, int iWidth, int iHeight, String sImgFilename ) { // adapt: Graphics2D | Graphics g.setColor( Color.white ); g.fillRect( 0, 0, iWidth, iHeight ); g.setColor( Color.blue ); g.drawRoundRect( 0, 0, iWidth-1, iHeight-1, 16, 16 ); g.setColor( Color.magenta ); g.fillRoundRect( 2, 2, iWidth-4, iHeight-4, 16, 16 ); g.setColor( Color.white ); g.fillOval( 2, 2, iWidth-4, iHeight-4 ); g.setColor( Color.black ); FontMetrics fm = g.getFontMetrics( g.getFont() ); String s = "" + iWidth + " x " + iHeight + " Pixel"; g.drawString( sImgFilename, iWidth/2 - fm.stringWidth(sImgFilename)/2, iHeight/2 ); g.drawString( s, iWidth/2 - fm.stringWidth(s)/2, iHeight/2 + fm.getHeight() ); } }
Seit Java 1.4 gibt es das Java Image I/O, mit dem sehr einfach verschiedene Grafikformate gespeichert werden können.
Eine Übersicht über die verfügbaren Dateiformate liefert:
System.out.println( Arrays.toString( ImageIO.getWriterFormatNames() ) );
Die folgende Klasse ImgImageIoStore definiert die abstrakte Methode myPaintFunction(), die in einer abgeleiteten Klasse überschrieben werden muss. Darin wird der Bildinhalt erstellt. Dies demonstriert das obige Beispiel MyImgStore (extends ImgImageIoStore beibehalten und statt x.png gewünschtes Dateiformat einsetzen).
Die Speicherung mit dem Java Image I/O sollte die bevorzugte Variante sein. Die anderen drei Varianten sollten nur Verwendung finden, wenn noch nicht Java 1.4 eingesetzt werden kann.
import java.awt.Graphics2D; import java.awt.image.BufferedImage; import java.io.File; import javax.imageio.ImageIO; public abstract class ImgImageIoStore { public abstract void myPaintFunction( Graphics2D g, int iWidth, int iHeight, String sImgFilename ); public void store( int iWidth, int iHeight, String sImgFilename ) throws Exception { BufferedImage img = new BufferedImage( iWidth, iHeight, BufferedImage.TYPE_INT_ARGB ); myPaintFunction( img.createGraphics(), iWidth, iHeight, sImgFilename ); try { ImageIO.write( img, "png", new File( sImgFilename ) ); } catch( Exception ex ) { throw new Exception( "\nError: Image storing to '" + sImgFilename + "' failed: " + ex.getMessage() ); } } }
ImgJpegStore ist eine einfache Klasse, die das Abspeichern von im Offscreen gemalten Bildern als JPEG-Datei erlaubt. Die Dateiendung muss .jpg oder .jpeg lauten.
Zu beachten ist, dass das JPEG-Format nur für realitätsnahe Bilder wie etwa Fotos oder für Bilder mit vielen Farbverläufen geeignet ist. Bei Texten, Strichzeichnungen, Charts und Cartoon-artigen Bildern ist die Qualität deutlich schlechter und die Dateigröße größer als im PNG- oder GIF-Format.
ImgJpegStore definiert die abstrakte Methode myPaintFunction(), die in einer abgeleiteten Klasse überschrieben werden muss. Darin wird der Bildinhalt erstellt. Dies demonstriert das obige Beispiel MyImgStore (ImgImageIoStore durch ImgJpegStore ersetzen und statt x.png muss x.jpg verwendet werden).
import java.io.*; import java.awt.*; import java.awt.image.*; import com.sun.image.codec.jpeg.*; public abstract class ImgJpegStore { public abstract void myPaintFunction( Graphics2D g, int iWidth, int iHeight, String sImgFilename ); public void store( int iWidth, int iHeight, String sImgFilename ) throws Exception { BufferedImage img = new BufferedImage( iWidth, iHeight, BufferedImage.TYPE_INT_RGB ); myPaintFunction( img.createGraphics(), iWidth, iHeight, sImgFilename ); try { FileOutputStream out = new FileOutputStream( new File( sImgFilename ) ); JPEGImageEncoder enc = JPEGCodec.createJPEGEncoder( out ); JPEGEncodeParam prm = enc.getDefaultJPEGEncodeParam( img ); prm.setQuality( 1.0f, false ); enc.setJPEGEncodeParam( prm ); enc.encode( img ); } catch( Exception ex ) { throw new Exception( "\nError: Image storing to '" + sImgFilename + "' failed: " + ex.getMessage() ); } } }
ImgJimiStore ist eine einfache Klasse, die das Abspeichern von im Offscreen gemalten Bildern erlaubt. Viele Dateiformate sind möglich, zum Beispiel PNG, JPG und BMP, aber nicht GIF. Das zu verwendende Format wird über die Dateiendung bestimmt. Welches Dateiformat optimal ist, kann am besten empirisch getestet werden. Dabei sollte auf Bildqualität und Dateigröße geachtet werden. Moderne Web-Browser verstehen PNG und JPG. PNG ist besonders für Texte, Strichzeichnungen, Charts und Cartoon-artige Bilder geeignet und JPG ist optimal für realitätsnahe Bilder wie etwa Fotos oder für Bilder mit vielen Farbverläufen.
ImgJimiStore definiert die abstrakte Methode myPaintFunction(), die in einer abgeleiteten Klasse überschrieben werden muss. Darin wird der Bildinhalt erstellt. Dies demonstriert das obige Beispiel MyImgStore (ImgImageIoStore durch ImgJimiStore ersetzen und statt x.png gewünschtes Dateiformat einsetzen).
Der Java-Classpath muss die JIMI-Bibliothek JimiProClasses.zip enthalten.
import java.awt.*; import java.awt.image.*; import com.sun.jimi.core.*; public abstract class ImgJimiStore { public abstract void myPaintFunction( Graphics2D g, int iWidth, int iHeight, String sImgFilename ); public void store( int iWidth, int iHeight, String sImgFilename ) throws Exception { BufferedImage img = new BufferedImage( iWidth, iHeight, BufferedImage.TYPE_INT_ARGB ); myPaintFunction( img.createGraphics(), iWidth, iHeight, sImgFilename ); try { Jimi.putImage( img, sImgFilename ); } catch( Exception ex ) { throw new Exception( "\nError: Image storing to '" + sImgFilename + "' failed: " + ex.getMessage() ); } } }
Die oben gezeigte Klasse ImgJimiStore benutzt BufferedImage, welches erst mit Java 2D ab Java 2 JDK 1.2 zur Verfügung steht. Das folgende Beispiel ImgPaintStore zeigt, wie ohne BufferedImage in den Offscreen gemalt werden kann.
Die Benutzung von ImgPaintStore kann wieder wie mit oben gezeigter Klasse MyImgStore erfolgen (ImgPaintStore statt ImgImageIoStore, paintAndStore statt store und Graphics statt Graphics2D).
ImgPaintStore demonstriert einige Schwierigkeiten, die ohne BufferedImage auftreten. Jimi.putImage() speichert ein Image, welches mit createImage() erzeugt wird. Ein gültiges Offscreen-Image, von welchem mit getGraphics() ein Graphics-Kontext erzeugt werden kann, liefert nur createImage() in der createImage(int,int)-Variante (und z.B. nicht createImage(MemoryImageSource)). createImage(int,int) returniert nur dann nicht null, wenn die dazugehörige Component (z.B. Canvas, Container, Frame) vorher aktiviert wurde, also der grafischen Oberfläche hinzugefügt wurde (z.B. mit add()) oder sichtbar geschaltet wurde (so wie hier mit setVisible(true)). Dies ist kein Problem, wenn das zu speichernde Bild sowieso auch angezeigt werden soll, aber macht es schwieriger, zum Beispiel Bilder mit anderer Farbkodierung oder größer als die Bildschirmanzeige zu generieren oder JavaBeans ohne sichtbare Komponenten zu entwickeln (z.B. in Server-seitigem Code).
import java.awt.*; import com.sun.jimi.core.*; public abstract class ImgPaintStore extends Frame { private Image img = null; private int wdth=0, hght=0; public abstract void myPaintFunction( Graphics g, int iWidth, int iHeight, String sImgFilename ); public void paintAndStore( int iWidth, int iHeight, String sImgFilename, int iSecondsShowImage ) throws Exception { wdth = iWidth; hght = iHeight; setVisible( true ); setVisible( ( 0 < iSecondsShowImage ) ? true : false ); img = createImage( iWidth, iHeight ); myPaintFunction( img.getGraphics(), iWidth, iHeight, sImgFilename ); update( getGraphics() ); try { Jimi.putImage( img, sImgFilename ); try { Thread.sleep( iSecondsShowImage * 1000 ); } catch( Exception ex ) { } } catch( Exception ex ) { throw new Exception( "\nImage storing to '" + sImgFilename + "' failed: " + ex.getMessage() ); } finally { dispose(); } } public void paint( Graphics g ) { Insets insts = getInsets(); setSize( wdth + insts.left + insts.right, hght + insts.top + insts.bottom ); if( null != img ) g.drawImage( img, insts.left, insts.top, this ); } }
import java.io.*; import org.apache.batik.transcoder.*; import org.apache.batik.transcoder.image.*; public class Svg2PngAndJpg { public static void main( String[] args ) { if( 1 > args.length || 5 > args[0].length() || 0 > args[0].indexOf( '.' ) ) { System.out.println( "Error: Parameter for .svg input file missing."); System.exit( 1 ); } try { Svg2Png( args[0] ); Svg2Jpg( args[0] ); System.exit( 0 ); } catch( Exception ex ) { ex.printStackTrace(); System.exit( 2 ); } } private static void Svg2Png( String file ) throws TranscoderException, IOException { PNGTranscoder t = new PNGTranscoder(); String svgURI = new File( file ).toURL().toString(); TranscoderInput input = new TranscoderInput( svgURI ); file = file.substring( 0, 1 + file.indexOf( '.' ) ) + "png"; OutputStream ostream = new FileOutputStream( file ); TranscoderOutput output = new TranscoderOutput( ostream ); t.transcode( input, output ); ostream.flush(); ostream.close(); } private static void Svg2Jpg( String file ) throws TranscoderException, IOException { JPEGTranscoder t = new JPEGTranscoder(); t.addTranscodingHint( JPEGTranscoder.KEY_QUALITY, new Float( .8 ) ); String svgURI = new File( file ).toURL().toString(); TranscoderInput input = new TranscoderInput( svgURI ); file = file.substring( 0, 1 + file.indexOf( '.' ) ) + "jpg"; OutputStream ostream = new FileOutputStream( file ); TranscoderOutput output = new TranscoderOutput( ostream ); t.transcode( input, output ); ostream.flush(); ostream.close(); } }Erliegen Sie nicht der Versuchung die beiden Zeilen