Bilder speichern mit Java
Für das Speichern von Bildern hat uns Sun Microsystems netterweise inzwischen mit dem Paket javax.imagio entsprechende Klassen zur Verfügung gestellt. Die genaue Realisierung der Speicherung wird hierbei wie so oft nicht zwingend durch Sun vorgegeben sondern kann von jedem als Service Provider uns bereitgestellt werden. Nichtsdestotrotz stellt die Java Runtime von Sun gleich einige ImageWriter bereit, hierunter auch einen für das Speichern von JPG Bildern mit Java.
Um ein Bild mit Java zu Speichern sind einige wenige Schritte notwendig:
- Suchen eines passenden ImageWriter
- (optional) Erzeugen eines Bildes
- Speichern das Bildes
Suchen eines passenden ImageWriter
Ein ImageWriter kann mit Hilfe der statischen Methode ImageIO.getImageWritersByFormatName (String extension) gefunden werden. Wollen wir z.B. ein JPG Bild mit Java speichern müssen wir lediglich als Extension eben "JPEG" angeben um den passenden ImageWriter oder genauer gesagt alle passenden ImageWriter zu finden.
Wenn wir allerdings dem Anwender das Format überlassen wollen ist es schöner diesem alle möglichen ImageWriter anzuzeigen. Zu diesem Zweck können wir uns mit der statischen Methode ImageIO.getWriterFormatNames() alle Formatnamen geben lassen. Im Quelltext kann dies zum Beispiel so aussehen:
ArrayList<Action> actions = new ArrayList<Action> ();
ImageWriter icoWriter = null;
for (String name: ImageIO.getWriterFormatNames()) {
boolean add = true;
// Prüfe, ob ein Action für diesen Writer bereits bekannt ist (durch Klassen)
for (Action a : actions) {
final Class c1 = ImageIO.getImageWritersByFormatName(name).next().getClass();
final Class c2 = ImageIO.getImageWritersByFormatName((String)a.getValue(Action.NAME)).next().getClass();
if (c1.equals(c2)) {
add = false;
break;
}
}
if (add) { // Falls neuer Writer füge diesen hinzu...
this.addWriter(actions, name);
}
}
Erzeugen eines Bildes
Um ein Bild (java.awt.Image) zu erzeugen können wir z.B. auf einem BufferedImage etwas über ein Graphics Objekt zeichnen. Im nachfolgenden Beispiel nutze zeige ich wie ich im SVG Viewer statt auf ein Panel einfach auf ein BufferedImage zeichne. Hierbei unterscheide ich noch, ob es sich um das WBMP Format handelt, da dort die Farbanzahl eingeschränkt ist.
Speichern des Bildes
Das Speichern eines Bildes mit Hilfe eines ImageWriter ist denkbar einfach. Wir müssen unserem ImageWriter Objekt in der Methode setOutput() lediglich einen OutputStream übergeben. Für unser java.awt.Image bedeutet dies einen MemoryCacheImageOutputStream zu verwenden.Nun aber endlich zur Fortsetzung unseres Beispiels von oben - die Methode addWriter.
Hinweis: Die Methode addWriter ist hierbei innerhalb der Klasse MainFrame definiert; grafik ist vom Typ (SVG)Panel.
protected void addWriter (final Collection forAdd, final String extensionToAdd) {
Action nAction = new ExtendedAction ("~"+extensionToAdd.toUpperCase()) {
public void actionPerformed (final ActionEvent e) {
final String extension = "."+this.getValue(Action.NAME);
JFileChooser jfc = new JFileChooser ();
jfc.setLocale (Locale.getDefault ());
jfc.updateUI ();
jfc.setCurrentDirectory (new File ());
switch (jfc.showSaveDialog (new JFrame())) {
case JFileChooser.APPROVE_OPTION:
try {
String name = jfc.getSelectedFile ().toString ();
if (!name.toLowerCase ().endsWith (extension)) {
name += extension;
}
final String ext = (String)this.getValue (Action.NAME);
BufferedImage bi = null;
if ("WBMP".equals (this.getValue (Action.NAME))) {
bi = new BufferedImage (MainFrame.this.grafik.getWidth (),
MainFrame.this.grafik.getHeight (),
BufferedImage.TYPE_BYTE_BINARY);
}
else {
bi = new BufferedImage (MainFrame.this.grafik.getWidth (),
MainFrame.this.grafik.getHeight (),
BufferedImage.TYPE_INT_RGB);
}
MainFrame.this.grafik.getDoc ().paint (new Component () {}, (Graphics2D) bi.getGraphics ());
writer.setOutput (new MemoryCacheImageOutputStream (new FileOutputStream (name)));
writer.write (bi);
bi.getGraphics ().dispose ();
writer.dispose ();
}
catch (FileNotFoundException ex) {
JOptionPane.showMessageDialog (new JFrame(),
ex.getLocalizedMessage (),
ex.getClass ().getName (),
JOptionPane.ERROR_MESSAGE);
}
catch (IOException ex) {
JOptionPane.showMessageDialog (new JFrame(),
ex.getLocalizedMessage (),
ex.getClass ().getName (),
JOptionPane.ERROR_MESSAGE);
}
}
}
};
}
Das war es auch schon...

