# Average-Color (Durchschnittsfarbe eines Bildes ermitteln)



## Wirtschaftsingenieur (6. Dez 2009)

Wie kann ich die Durchschnittsfarbe eines Bildes ermitteln?

So lese ich eine Bilddatei ein und erzeuge eine neue Datei:

```
// Laden einer bestehenden Bilddatei
ImageFrame f = new ImageFrame(new File("src/xy/images/beispiel.jpg"), "Name des Bildes"); f.setVisible (true);
// Neues Bild "f1" erzeugen und Bildinhalt von "f" reinkopieren
ImageFrame f1 = new ImageFrame(f.getImageWidth(), f.getImageHeight(), "Name des neuen Bildes");
for (int y = 0; y<f.getImageHeight(); y++)
for (int x = 0; x<f.getImageWidth(); x++)
{
f1.setRGB(x, y, f.getRGB(x, y));
}
```

So erzeuge ich beispielsweise ein Negativ-Bild:

```
// RGB-Farbwert lesen
int color = f1.getRGB(x, y);
// RGB zerlegen in die drei Grundfarben
int r = (color >> 16) & 0xFF;
int g = (color >> 8) & 0xFF;
int b = color & 0xFF;
// Negativ Farbinensitäten bilden
r = 255 - r;
g = 255 - g;
b = 255 - b;
color = (0xFF<<24)|(r<<16)|(g<<8)| b;
f1.setRGB(x, y, color);
}
}
f1.setVisible(true);
```

Danke für eure Hilfe


----------



## faetzminator (6. Dez 2009)

Du zählst einfach alle R, G und B-Werte zusammen und teilst sie durch die Anzahl Pixel.


----------



## Wirtschaftsingenieur (6. Dez 2009)

Wie komm ich auf die gesamte Pixelanzahl? Und wie auf die jeweiligen Anteile von R, G, B.


----------



## faetzminator (6. Dez 2009)

Was für eine Klasse [c]ImageFrame[/c] ist das denn?


----------



## Wirtschaftsingenieur (6. Dez 2009)

Hier die Klasse ImageFrame:

```
/**
 * 
 */
package xy.plot;

import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Paint;
import java.awt.Shape;
import java.awt.Stroke;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.awt.print.PageFormat;
import java.awt.print.Printable;
import java.awt.print.PrinterException;
import java.awt.print.PrinterJob;
import java.io.File;
import java.util.Map;

import javax.swing.JFrame;
import javax.swing.UIManager;

import xy.plot.tools.ImagePanel;

/**
 * Rasterbilder in einem Fenster (Frame) darstellen.
 * <p>
 * Dieser Frame (<code>java.swing.JFrame</code>) dient als eigenständiges Fenster (<code>ContentPane</code>) zum 
 * Darstellen und Bearbeiten von Rasterbildern. Es kann auf einzelne Pixel des Bildrasters lesend oder schreibend 
 * zugegriffen werden (setRGB()/getRGB()). Die Auswahl eines bestimmten Pixels erfolgt durch die Angabe eines 
 * xy-Koordinatenpaares, wobei die linke obere Ecke des Bildes der Koordinatenursprung (0,0) ist.
 * Die Größe des Bildrasters in Breite und Höhe (jeweils in Pixel) wird im Konstruktor festgelegt
 * und kann nachträglich nicht mehr verändert werden (non mutable). Es kann ein Raster jeder gewünschten Größe 
 * angelegt werden, welches mit der Standard-Farbe schwarz initialisiert wird. Oder es kann eine Bild-Datei vom Typ 
 * .gif, .jpg, .bmp, ... geladen werden, wobei die Größe des Rasters mit der Größe der Bild-Datei
 * initialisiert wird. Es existiert auch ein Konstruktor, der eine angegebene Bild-Datei in eine gewünschte
 * Größe umsetzt (siehe Konstruktoren).
 * <p>
 * Nach der Erzeugung (Konstruktion) einer neuen Instanz der Klasse <code>ImageFrame</code> bleibt das Fenster 
 * zunächst unsichtbar. Deshalb kann der Bildinhalt zu nächst nicht sichtbar bearbeitet werden. Mit der Methode
 * <code>setVisible(true)</code> und dem Parameter <code>true</code> wird das Fenster und der Bildinhalt sichtbar. 
 * Die Größe des Fensters wird an die Größe des Bildrasters angepasst; kann aber durch Ziehen verändert werden. 
 * <p>
 * Nachdem ein Fenster sichtbar wurde, wird der Bildinhalt bei Veränderung nicht automatisch aktualisiert, d.h. 
 * die Veränderungen am Bildinhalt werden nicht sichtbar. Mit Hilfe der Methode <code>repaint()</code> und deren 
 * Varianten kann eine Aktualisierung des Fensters angefordert werden.  
 * <p>
 * <b>Beispiel-Code:</b>
 * <p>
 * <code>
 * // Erstellen eines neuen Fensters mit schwarzem Bildinhalt der Groesse 800x600 Pixel <br>  
 * ImageFrame frame = new ImageFrame(800,600); <br>
 * // Verändern der Farbe eines einzelnen Pixels zu gelb, Position x=100, y=33 <br>
 * frame.setRGB(100,33,0xFFFF00); <br>
 * // Sichtbar machen des Fensters <br> 
 * frame.setVisible(true); <br>
 * </code> 
 * @author MaBe
 * @version 1.2
 * @see java.swing.JFrame
 */
public class ImageFrame extends JFrame implements Printable
{
	private static final long serialVersionUID = 4953658294908426545L;

	// Content-Pane
	private ImagePanel pane;

	
	/**
	 * Einen neuen, noch unsichtbaren Frame mit einem Bild-Raster der angegebenen Größe und dem angegebenen Titel erzeugen. 
	 * Der angegebene Titel wir in der Titelleiste des Fensters angezeigt.
	 * Mit setVisible(true) sichtbar machen.
	 *
	 * @param width Breite des Raster-ImagePanels in Pixel 
	 * @param height Höhe des Raster-ImagePanels in Pixel
	 * @param titel Titel in der Fensterleiste 
	 */
	public ImageFrame(int width, int height, String titel)
	{
    	this(titel, new ImagePanel(width, height));
 	}
	
	/**
	 * Einen neuen, noch unsichtbaren Frame mit einem Bild-Raster der angegebenen Größe 
	 * als ContentPane erzeugen. 
	 * In der Titelleiste des Fensters wird ein vorgegebener Titel gezeigt.
	 * Mit setVisible(true) sichtbar machen.
	 *
	 * @param width Breite des Raster-ImagePanels in Pixel 
	 * @param height Höhe des Raster-ImagePanels in Pixel 
	 */
	public ImageFrame(int width, int height)
	{
    	this("Raster-Image Viewer", new ImagePanel(width, height));
 	}
	
	/**
	 * Einen neuen, noch unsichtbaren Frame mit einem Rasterbild aus einer Bilddatei erzeugen. 
	 * In der Titelleiste des Fensters wird ein vorgegebener Titel gezeigt.
	 * Die angegebene Datei wird als Bildinhalt geladen. Die Größe des Bild-Rasters entspricht 
	 * der Größe der geladenen Bild-Datei.
	 * Mit setVisible(true) sichtbar machen.
	 *
	 * @param file Bild-Datei als <code>File</code> Objekt 
	 */
	public ImageFrame(File file)
	{
    	this("Raster-Image Viewer", new ImagePanel(file, null));
 	}
	
	/**
	 * Einen neuen, noch unsichtbaren Frame mit einem Rasterbild aus einer Bilddatei und dem angegebenen Titel erzeugen. 
	 * In der Titelleiste des Fensters wird der angegebene Titel gezeigt.
	 * Die angegebene Datei wird als Bildinhalt geladen. Die Größe des Bild-Rasters entspricht 
	 * der Größe der geladenen Bild-Datei.
	 * Mit setVisible(true) sichtbar machen.
	 *
	 * @param file Bild-Datei als <code>File</code> Objekt
	 * @param titel Titel in der Fensterleiste 
	 */
	public ImageFrame(File file, String titel)
	{
    	this(titel, new ImagePanel(file, null));
 	}
	
	/**
	 * Einen neuen, noch unsichtbaren Frame mit einem Rasterbild aus einer Bilddatei 
	 * und dem angegebenen Titel erzeugen. Der Bildinhalt wird mit der angegebenen Bild-Datei initialisiert.
	 * Dabei wird das angegebene Bild auf die gewünschte Rastergröße skaliert. 
	 * In der Titelleiste des Fensters wird der angegebene Titel gezeigt.
	 * Mit <code>setVisible(true)</code> sichtbar machen.
	 *
	 * @param width Breite des Raster-ImagePanels in Pixel 
	 * @param height Höhe des Raster-ImagePanels in Pixel
	 * @param file Bild-Datei als <code>File</code> Objekt, wird geladen und skaliert
	 * @param titel Titel in der Fensterleiste 
	 */
	public ImageFrame(int width, int height, File file, String titel)
	{
    	this(titel, new ImagePanel(width, height, file, null));
 	}
	
	/**
	 * Einen neuen, noch unsichtbaren Frame mit einem <code>ImagePanel</code> als ContentPane erzeugen. 
	 * Der angegebene Name erscheint in der Titelleiste des Fensters.
	 * Mit setVisible(true) sichtbar machen.
	 * <p>
	 * Für interne Verwendung!
	 *
	 * @param titel Titel des Fensters in der Titelleiste
	 * @param p zugehöriges ContentPane (<code>ImagePanel</code>)
	 */
	public ImageFrame(String titel, ImagePanel p)
	{
		setSystemLookAndFeel();
		JFrame.setDefaultLookAndFeelDecorated(true);
		pane = p;
		this.setDefaultCloseOperation(ImageFrame.EXIT_ON_CLOSE);
 		this.setContentPane(pane);
    	this.setTitle(titel);
    	this.addWindowListener(p);
        this.pack();
        // this.g2d = pane.getGraphics2D();
 	}
	
	/**
	 * Einen neuen, noch unsichtbaren Frame mit einem <code>ImagePanel</code> als ContentPane erzeugen. 
	 * Der angegebene Name erscheint in der Titelleiste des Fensters. Der Rahmen des darstellenden Fensters
	 * kann ausgeblendet werden (<code>undecorated = true</code>). 
	 * Mit setVisible(true) sichtbar machen.
	 *
	 * @param titel Titel des Fensters in der Titelleiste
	 * @param p zugehöriges ContentPane (<code>ImagePanel</code>)
	 * @param undecorated true falls kein Fensterrahmen gezeigt werden soll
	 */
	public ImageFrame(String titel, ImagePanel p, boolean undecorated)
	{
		super(titel);
		setSystemLookAndFeel();
		JFrame.setDefaultLookAndFeelDecorated(true);
		this.pane = p;
		this.setUndecorated(undecorated);
		this.setDefaultCloseOperation(ImageFrame.EXIT_ON_CLOSE);
 		this.setContentPane(pane);

    	// this.setTitle(titel);
    	this.addWindowListener(p);
        pack();
 	}

	
	/**
	 * Einstellen des jeweiligen system-spezifischen GUI-Aussehens (Look-and-Feel).
	 * Diese Methode sollte vor dem ersten Erstellen eines Fensters einmalig aufgerufen werden, 
	 * um das jeweils systemspezifische Aussehen eines Fensters zu erhalten.
	 *  
	 */
	public static void setSystemLookAndFeel()
	{
		try
		{
			// set up system look-and-feel
			UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
		} catch (Exception e)
		{
			e.printStackTrace();
		} 		
	}
		
	/**
	 * Access to the destination image's buffer <code>BufferedImage</code>
	 * @return the buffered image
	 */
	protected BufferedImage getBufferedImage()
	{
		return pane.getBufferedImage();
	}
	
	/**
	 * Liefert die Breite des Frame-Inhalts in Pixel
	 * 
	 * @return die Rasterbreite in Pixel
	 */
	public int getImageWidth()
	{
		return pane.getImageWidth();
	}
	
	/**
	 * Liefert die Höhe des Frame-Inhalts in Pixel
	 * 
	 * @return die Rasterhöhe in Pixel
	 */
	public int getImageHeight()
	{
		return pane.getImageHeight();
	}
		
	/**
	 * Setzen der Farbe eines Pixels im Bildraster. 
	 * <p>
	 * Die angegebenen Pixelkoordinaten (x,y) müssen 
	 * im Bereich des Rasters (x = 0...width-1, y = 0...height-1) liegen. Die angegebene Farbe ist 
	 * eine 32bit Farbangabe mit 0xAARRGGBB (hexadezimal jeweils 8 bit für Alpha, Rot, Grün, Blau).
	 * Der Alpha-Wert findet derzeit keine Verwendung, da nur ein Bild deckend dargestellt wird.
	 * 
	 * @param x, x-Koordinate des Pixels
	 * @param y, y-Koordinate des Pixels
	 * @param rgb, Farbcodierung 32 bit, jeweils 8-bit für Alpha, Rot, Grün, Blau
	 */
	public void setRGB(int x, int y, int rgb)
	{
		if (x >= 0 && x < pane.getImageWidth() && y >= 0 && y < pane.getImageHeight())
			pane.setRGB(x, y, rgb);
	}
	
	/**
	 * Auslesen der Farbe eines Pixels im Bildraster. 
	 * <p>
	 * Die angegebenen Pixelkoordinaten (x,y) müssen 
	 * im Bereich des Rasters (x = 0...width-1, y = 0...height-1) liegen. Der zurückgelieferte Farbcode ist 
	 * eine 24bit Farbangabe mit 0x00RRGGBB (hex).
	 * 
	 * @param x x-Koordinate des Pixels
	 * @param y yKoordinate des Pixels
	 * @return RGB-Farbcodierung 24 bit, jeweils 8-bit für Rot, Grün, Blau
	 */
	public int getRGB(int x, int y)
	{
		if (x >= 0 && x < pane.getImageWidth() && y >= 0 && y < pane.getImageHeight())
			return pane.getRGB(x, y);
		else
			return 0;
	}

	/**
	 * Liefert die aktuell eingestellte Füll- und Stiftfarbe für alle elementaren 
	 * Zeichenfunktionen.
	 * 
	 * @return RGB Farbcodierung 32 bit, jeweils 8-bit für Rot, Grün, Blau, Alpha wird nicht benützt
	 */
	public int getColor()
	{
		return pane.getColor();
	}

	/**
	 * Einstellen der aktuellen Füll- und Stiftfarbe für alle elementaren 
	 * Zeichenfunktionen.
	 * 
	 * @param color Farbcodierung 32 bit, jeweils 8-bit für Alpha, Rot, Grün, Blau
	 */
	public void setColor(int color)
	{
		pane.setColor(color);
	}
	
	/**
	 * Füllen des gesamten Bildrasters mit der aktuell eingestellten Füll- und Stiftfarbe
	 * (Löschen) und aktualisieren des Fensters.
	 */
	public void clear()
	{
		pane.clear();
		pane.repaint();
	}
	
	/**
	 * Füllen eines rechteckigen Bereichs mit der aktuell eingestellten Füll- und Stiftfarbe.
	 * Die angegebenen Koordinaten entsprechen der linken oberen Ecke des Rechtecks; die Größe 
	 * wird mit width und height festgelegt.
	 * 
	 * @param x
	 * @param y
	 * @param width
	 * @param height
	 * @see java.awt.Graphics#clearRect(int, int, int, int)
	 */
	public void clearRect(int x, int y, int width, int height)
	{
		pane.getGraphics2D().clearRect(x, y, width, height);
	}

	/**
	 * Zeichnen der Umrisse einer beliebigen geometrischen Figur (<code>Shape</code>) unter 
	 * Verwendung des aktuell eingestellten Stifts (<code>Stroke</code>).
	 * 
	 * @param s eine geometrische Figur
	 * @see java.awt.Graphics2D#draw(java.awt.Shape)
	 */
	public void draw(Shape s)
	{
		pane.getGraphics2D().draw(s);
	}

	/**
	 * Zeichnen eines Kreis-/Ellipsensegments.
	 * 
	 * @param x
	 * @param y
	 * @param width
	 * @param height
	 * @param startAngle
	 * @param arcAngle
	 * @see java.awt.Graphics#drawArc(int, int, int, int, int, int)
	 */
	public void drawArc(int x, int y, int width, int height, int startAngle, int arcAngle)
	{
		pane.getGraphics2D().drawArc(x, y, width, height, startAngle, arcAngle);
	}

	/**
	 * Zeichnen einer Linie zwischen zwei Punkten P1(x1,y1) und P2(x2,y2)
	 * 
	 * @param x1 x-Koordinate des ersten Punkts
	 * @param y1 y-Koordinate des ersten Punkts
	 * @param x2 x-Koordinate des zweiten Punkts
	 * @param y2 y-Koordinate des zweiten Punkts
	 * @see java.awt.Graphics#drawLine(int, int, int, int)
	 */
	public void drawLine(int x1, int y1, int x2, int y2)
	{
		pane.getGraphics2D().drawLine(x1, y1, x2, y2);
	}

	/**
	 * Zeichnen der Umrisse eine Ellipse, die in dem angegebenen Rechteck einbeschrieben ist.
	 * 
	 * @param x
	 * @param y
	 * @param width
	 * @param height
	 * @see java.awt.Graphics#drawOval(int, int, int, int)
	 */
	public void drawOval(int x, int y, int width, int height)
	{
		pane.getGraphics2D().drawOval(x, y, width, height);
	}

	/**
	 * Zeichnen der Umrisse eines Polygones mit den angegebenen Eckpunkten.
	 * 
	 * @param xPoints x-Koordinaten aller Eckpunkte
	 * @param yPoints y-Koordinaten aller Eckpunkte
	 * @param nPoints Anzahl der Eckpunkte
	 * @see java.awt.Graphics#drawPolygon(int[], int[], int)
	 */
	public void drawPolygon(int[] xPoints, int[] yPoints, int nPoints)
	{
		pane.getGraphics2D().drawPolygon(xPoints, yPoints, nPoints);
	}

	/**
	 * Zeichnen einer Verbindungslinie von mehreren gegebenen Punkten.
	 * @param xPoints x-Koordinaten aller Eckpunkte
	 * @param yPoints y-Koordinaten aller Eckpunkte
	 * @param nPoints Anzahl der Eckpunkte
	 * @see java.awt.Graphics#drawPolyline(int[], int[], int)
	 */
	public void drawPolyline(int[] xPoints, int[] yPoints, int nPoints)
	{
		pane.getGraphics2D().drawPolyline(xPoints, yPoints, nPoints);
	}

	/**
	 * Zeichnen der Umrisse eines Rechtecks.
	 * 
	 * @param x x-Koordinate der linken, oberen Ecke des Rechtecks
	 * @param y y-Koordinate der linken, oberen Ecke des Rechtecks
	 * @param width Breite des Rechtecks in Pixel
	 * @param height Höhe des Rechtecks in Pixel
	 * @see java.awt.Graphics#drawRect(int, int, int, int)
	 */
	public void drawRect(int x, int y, int width, int height)
	{
		pane.getGraphics2D().drawRect(x, y, width, height);
	}

	/**
	 * Darstellen eines Textes als Grafik.
	 * 
	 * @param str der darzustellende Text
	 * @param x x-Koordinate der Textposition
	 * @param y y-Koordinate der Textposition
	 * @see java.awt.Graphics2D#drawString(java.lang.String, int, int)
	 */
	public void drawString(String str, int x, int y)
	{
		pane.getGraphics2D().drawString(str, x, y);
	}
	
	
	/**
	 * Darstellen eines Bildes an der angegebenen Position in Originalgröße (keine Skalierung).
	 * 
	 * @param img Bild Objekt
	 * @param x x-Koordinate der linken, oberen Ecke des Bildes
	 * @param y y-Koordinate der linken, oberen Ecke des Bildes
	 * @return
	 */
	public boolean drawImage(Image img, int x, int y)
	{
		return pane.getGraphics2D().drawImage(img, x, y, pane);
	}

	/**
	 * Darstellen eines Bildes an der angegebenen Position und in der angegebenen Größe (Skalierung).
	 * 
	 * @param img Bild Objekt
	 * @param x x-Koordinate der linken, oberen Ecke des Bildes
	 * @param y y-Koordinate der linken, oberen Ecke des Bildes
	 * @param width Breite der Darstellung in Pixel
	 * @param height Höhe der Darstellung in Pixel
	 * @return
	 * @see java.awt.Graphics#drawImage(java.awt.Image, int, int, int, int, java.awt.image.ImageObserver)
	 */
	public boolean drawImage(Image img, int x, int y, int width, int height)
	{
		return pane.getGraphics2D().drawImage(img, x, y, width, height, pane);
	}

	/**
	 * @param img
	 * @param dx1
	 * @param dy1
	 * @param dx2
	 * @param dy2
	 * @param sx1
	 * @param sy1
	 * @param sx2
	 * @param sy2
	 * @return
	 * @see java.awt.Graphics#drawImage(java.awt.Image, int, int, int, int, int, int, int, int, java.awt.image.ImageObserver)
	 */
	public boolean drawImage(Image img, int dx1, int dy1, int dx2, int dy2, int sx1, int sy1, int sx2, int sy2)
	{
		return pane.getGraphics2D().drawImage(img, dx1, dy1, dx2, dy2, sx1, sy1, sx2, sy2, pane);
	}

	/**
	 * Füllen einer beliebigen geometrischen Figur (<code>Shape</code>) unter 
	 * Verwendung des aktuell eingestellten Füllmusters (<code>Paint</code>).
	 * 
	 * @param s eine geometrische Figur
	 * @see java.awt.Graphics2D#draw(java.awt.Shape)
	 */
	public void fill(Shape s)
	{
		pane.getGraphics2D().fill(s);
	}

	/**
	 * @param x
	 * @param y
	 * @param width
	 * @param height
	 * @param startAngle
	 * @param arcAngle
	 * @see java.awt.Graphics#fillArc(int, int, int, int, int, int)
	 */
	public void fillArc(int x, int y, int width, int height, int startAngle, int arcAngle)
	{
		pane.getGraphics2D().fillArc(x, y, width, height, startAngle, arcAngle);
	}

	/**
	 * @param x
	 * @param y
	 * @param width
	 * @param height
	 * @see java.awt.Graphics#fillOval(int, int, int, int)
	 */
	public void fillOval(int x, int y, int width, int height)
	{
		pane.getGraphics2D().fillOval(x, y, width, height);
	}

	/**
	 * @param xPoints
	 * @param yPoints
	 * @param nPoints
	 * @see java.awt.Graphics#fillPolygon(int[], int[], int)
	 */
	public void fillPolygon(int[] xPoints, int[] yPoints, int nPoints)
	{
		pane.getGraphics2D().fillPolygon(xPoints, yPoints, nPoints);
	}

	/**
	 * @param x
	 * @param y
	 * @param width
	 * @param height
	 * @see java.awt.Graphics#fillRect(int, int, int, int)
	 */
	public void fillRect(int x, int y, int width, int height)
	{
		pane.getGraphics2D().fillRect(x, y, width, height);
	}

	/**
	 * @return
	 * @see java.awt.Graphics2D#getPaint()
	 */
	public Paint getPaint()
	{
		return pane.getGraphics2D().getPaint();
	}

	/**
	 * @return
	 * @see java.awt.Graphics2D#getStroke()
	 */
	public Stroke getStroke()
	{
		return pane.getGraphics2D().getStroke();
	}

	/**
	 * @return
	 * @see java.awt.Graphics2D#getTransform()
	 */
	public AffineTransform getTransform()
	{
		return pane.getGraphics2D().getTransform();
	}

	/**
	 * @param paint
	 * @see java.awt.Graphics2D#setPaint(java.awt.Paint)
	 */
	public void setPaint(Paint paint)
	{
		pane.getGraphics2D().setPaint(paint);
	}

	/**
	 * @param hints
	 * @see java.awt.Graphics2D#setRenderingHints(java.util.Map)
	 */
	public void setRenderingHints(Map<?, ?> hints)
	{
		pane.getGraphics2D().setRenderingHints(hints);
	}

	/**
	 * @param s
	 * @see java.awt.Graphics2D#setStroke(java.awt.Stroke)
	 */
	public void setStroke(Stroke s)
	{
		pane.getGraphics2D().setStroke(s);
	}

	/**
	 * @param Tx
	 * @see java.awt.Graphics2D#setTransform(java.awt.geom.AffineTransform)
	 */
	public void setTransform(AffineTransform Tx)
	{
		pane.getGraphics2D().setTransform(Tx);
	}

	/**
	 * @param Tx
	 * @see java.awt.Graphics2D#transform(java.awt.geom.AffineTransform)
	 */
	public void transform(AffineTransform Tx)
	{
		pane.getGraphics2D().transform(Tx);
	}
	
	/**
	 * Access to the Graphics2D object.
	 *  
	 * @return the corresponding Graphics2D object
	 */
	public Graphics2D getGraphics2D()
	{
		return pane.getGraphics2D();
	}

    
    // Baustelle !
    public void print()
    {
    	// Get a PrinterJob      
    	PrinterJob job = PrinterJob.getPrinterJob();      
    	// Specify the Printable is an instance of SimplePrint2D 
    	job.setPrintable(null);      
    	// Put up the dialog box      
    	if (job.printDialog())  
    	{ 	 
    		// Print the job if the user didn't cancel printing  
    		try { job.print(); } 	     
    		catch (Exception e) { /* handle exception */ }      
    	}      	
    }

	public int print(Graphics graphics, PageFormat pageFormat, int pageIndex) throws PrinterException
	{
		if (pageIndex > 0) 
			return Printable.NO_SUCH_PAGE; 
		
		Graphics2D g = (Graphics2D)graphics;
		Dimension  d = pane.getSize();

		Dimension  dprev =  d;  // this.getPreferredSize();
		pane.setSize(dprev);

		// g.setClip((int)pageFormat.getImageableX(), (int)pageFormat.getImageableY(), (int)pageFormat.getImageableWidth(), (int)pageFormat.getImageableHeight());
		g.translate(pageFormat.getImageableX(), pageFormat.getImageableY());
		double scale = Math.min(pageFormat.getImageableWidth() / dprev.width, pageFormat.getImageableHeight() / dprev.height);
		g.scale(scale, scale);

		pane.paint(g);
		// this.setSize(d);
		return Printable.PAGE_EXISTS;
	}


	/**
	 * 1. Beispiel-Applikation.
	 * Zeichnen eines Musters (zufällig und sinnlos)
	 * 
	 * @param args not used
	 */
	public static void main(String args[])
	{
		// Zeichnen der Plots
		final int width = 700, height = 480;
		ImageFrame f = new ImageFrame(width, height);		
		f.setVisible(true);
		
		for (int x=0; x<width; x++)
			for (int y=0; y<height; y++)
			{
				int r = (int)(256 * Math.sqrt((double)(x*x + y*y) / (width*width + height*height))) & 0xFF;
				int g = (x ^ y) & 0xFF;
				int b = (int)(Math.random()*256.0);
				int a = (x>>>3)%2 == 0 ? 128 : 255;
				
				int argb = (a<<24)|(r<<16)|(g<<8)|b;
				f.setRGB(x, y, argb);
			}
		f.repaint();
		
		f.setColor(0xFFFFD020);
		f.drawLine(0, 0, width-1, height-1);
		f.repaint();
	}

	/**
	 * 2.Beispiel-Applikation.
	 * Plotten der Höhenwerte (y-Werte) einer Funktion zweier Veränderlicher.
	 * 
	 * @param args not used     
	 */
	public static void main1(String args[])
	{
		// Zeichnen der Plots
		final int width = 800, height = 600;
		ImageFrame f = new ImageFrame(width, height);		
		
		for (int x=0; x<width; x++)
			for (int y=0; y<height; y++)
			{
				// Koordinaten-Range
				double xo = 2.0*(double)x/width - 1.0;  // -1 ... 1
				double yo = - (2.0*(double)y/height - 1.0); // -1 ... 1
				
				// Funktion
				double z = xo*yo/(xo*xo+yo*yo);
				
				// Farbe generieren
				int h = (int)Math.round(255*2*z);
				
				int r = h > 0? h : 0;
				int g = h > 0? 255-h : 255 + h;
				int b = h > 0? 0 : -h;
				int a = 0xFF;
				
				int argb = (a<<24)|(r<<16)|(g<<8)|b;
				f.setRGB(x, y, argb);
			}
		
		f.setVisible(true);
	}

	/**
	 * 3.Beispiel-Applikation.
	 * Laden einer existierenden Bilddatei. 
	 * 
	 * @param args not used     
	 */
	public static void main3(String args[])
	{
		// Darstellen einer Bilddatei
		ImageFrame f = new ImageFrame(new File("src/xy/plot/images/maske.gif"));				
		f.setVisible(true);
	}

}
```


----------



## faetzminator (6. Dez 2009)

Und [c]ImagePanel[/c]  ?


----------



## Wirtschaftsingenieur (6. Dez 2009)

Hier ImagePanel:

```
package xy.plot.tools;

import java.awt.Color;
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.MouseEvent;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import java.awt.image.BufferedImage;
import java.awt.image.ColorModel;
import java.awt.image.IndexColorModel;
import java.awt.image.WritableRaster;
import java.awt.print.PageFormat;
import java.awt.print.Printable;
import java.awt.print.PrinterException;
import java.awt.print.PrinterJob;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JSeparator;
import javax.swing.event.MouseInputAdapter;
import javax.swing.filechooser.FileNameExtensionFilter;

import xy.plot.ImageFrame;

/**
 * This class shows a buffered image within a JPanel. 
 * The size is given within the constructor
 * and may not be changed.
 * 
 * @author MaBe
 *
 */
public class ImagePanel extends JPanel implements WindowListener, Printable
{
	private static final long serialVersionUID = -3747955137230037528L;
	private static final int  bufferedImageType = BufferedImage.TYPE_INT_RGB;
	private static final Color  defaultColor = Color.lightGray;
	private static Object[][]   defaultRenderingHints =
	{
		{RenderingHints.KEY_RENDERING,       RenderingHints.VALUE_RENDER_QUALITY},
		{RenderingHints.KEY_ANTIALIASING,    RenderingHints.VALUE_ANTIALIAS_ON}, 
		{RenderingHints.KEY_INTERPOLATION,   RenderingHints.VALUE_INTERPOLATION_BICUBIC},
		{RenderingHints.KEY_DITHERING,       RenderingHints.VALUE_DITHER_DISABLE},
		{RenderingHints.KEY_COLOR_RENDERING, RenderingHints.VALUE_COLOR_RENDER_QUALITY}
	};
	
	private ImagePanel   parent = null; 
	
	private int           width, height;
	private BufferedImage bufferedImage;
	private Graphics2D    g2d;
	
	private RectangleSelectionHandler  mouseHandler = null;
	private JPopupMenu   popupMenu = null;
	private Action       saveAction  = null;
	private Action       closeAction = null;
	private Action       printAction = null;
	private JFileChooser fileChooser = null;
	
	/**
	 * Create an empty image-raster with no parent, and given size.
	 * 
	 * @param width destination width of the created raster
	 * @param height destination height of the created raster
	 */
	public ImagePanel(int width, int height)
	{
		this(width, height, (File)null, null);	
	}
	
	/**
	 * Create an empty image-raster with given parent and given size.
	 * 
	 * @param width destination width of the created raster
	 * @param height destination height of the created raster
	 */
	public ImagePanel(int width, int height, ImagePanel parent)
	{
		this(width, height, (File)null, parent);
	}
	
	/**
	 * Create an image-raster of the given image-file and with given parent.
	 * 
	 * @param file image-file to load
	 * @param parent ImagePanel
	 */
	public ImagePanel(File file, ImagePanel parent)
	{
		this(-1, -1, file, parent);
	}
	
	/**
	 * Create an image-raster with given parent and given size. Initialize the 
	 * raster-image with the scaled given image-file.
	 * 
	 * @param width destination width of the created raster, or -1 to use the file's size
	 * @param height destination height of the created raster, or -1 to use the file's size
	 * @param file image-file to load
	 * @param parent ImagePanel, optional may be null
	 */
	public ImagePanel(int width, int height, File file, ImagePanel parent)
	{
		init(width, height, parent);		
		this.bufferedImage = getBufferedImage(file);
	}
	
	
	/**
	 * Create an image-raster with given parent, given size and a given ColorModel. 
	 * 
	 * @param width destination width of the created raster
	 * @param height destination height of the created raster
	 * @param color-model to use for this raster
	 * @param parent ImagePanel, optional may be null
	 */
	public ImagePanel(int width, int height, ColorModel cmodel, ImagePanel parent)
	{
		init(width, height, parent);		
		this.bufferedImage = getBufferedImage(cmodel);
	}
	
	private BufferedImage getBufferedImage(ColorModel model)
	{
		if (bufferedImage == null)
		{
			WritableRaster raster = model.createCompatibleWritableRaster(width, height);
			bufferedImage = new BufferedImage(model, raster, false, null);
			g2d = bufferedImage.createGraphics();
			g2d.setRenderingHints(getRenderingHints());
			g2d.setColor(defaultColor);	
			g2d.drawRect(0, 0, width, height);
		}
		return bufferedImage;
	}
	
	
	/*
	 * Common initialization.
	 */
	private void init(int width, int height, ImagePanel parent)
	{
		this.width = width;
		this.height = height;
		this.parent = parent;
		
		this.mouseHandler = new RectangleSelectionHandler(this);
		this.addMouseListener(mouseHandler);
		this.addMouseMotionListener(mouseHandler);		
		this.popupMenu = getPopupMenu();
	}

	/**
	 * Dispose all resources, especially the Graphics2D object.
	 */
	public void dispose()
	{
		if (g2d != null)
			g2d.dispose();
		g2d = null;
		bufferedImage = null;
	}
	
	
	/**
	 * Creates or gets, if already created, the panel's popup-menue.
	 * 
	 * @return the popup-menue
	 */
	public JPopupMenu getPopupMenu()
	{
		if (popupMenu == null)
		{
			JLabel label = new JLabel(" Raster-Image ");
			label.setHorizontalAlignment(JLabel.CENTER);
			label.setHorizontalTextPosition(JLabel.CENTER);
			popupMenu = new JPopupMenu("Raster-Bild");
			popupMenu.add(label);
			popupMenu.add(new JSeparator());
			popupMenu.add(getSaveAction());
			popupMenu.add(getPrintAction());
			popupMenu.add(new JSeparator());
			popupMenu.add(getCloseAction());
		}
		return popupMenu;
	}
	
	/**
	 * Creates or gets, if already created, the panel's close action.
	 * This Action disposes the corresponding window.
	 * 
	 * @return the action object
	 */
	public Action getCloseAction()
	{
		if (closeAction == null)
		{	closeAction = new AbstractAction("Schließen")
			{	private static final long serialVersionUID = 0L;
				public void actionPerformed(ActionEvent e)
				{
					Container win = ImagePanel.this.getTopLevelAncestor();
					if (win instanceof Window)
					{
						((Window)win).dispose();
					}
				}
			};
		}
		return closeAction;
	}
	
	/**
	 * Creates or gets, if already created, the panel's image-save action.
	 * 
	 * @return the action object
	 */
	public Action getSaveAction()
	{
		if (saveAction == null)
		{
			saveAction = new AbstractAction("Speichern")
			{
				private static final long serialVersionUID = 0L;

				public void actionPerformed(ActionEvent e)
				{
				    int returnVal = getFileChooser().showSaveDialog(ImagePanel.this);
				    if(returnVal == JFileChooser.APPROVE_OPTION) 
				    {
				    	File file = fileChooser.getSelectedFile();
				    	String name = file.getName();
				    	String extension = "jpg";
			        	int i = name.lastIndexOf(".");
			        	if (i > 0 && i < name.length()-1)
			        		extension = name.substring(i+1, name.length());
			        	else
			        		file = new File(file.getParent(), name+"."+extension);
			        	
				        ImagePanel.this.saveImage(file, extension);
				    }
				}
			
			};
		}
		return saveAction;
	}
	
	/**
	 * Creates or gets, if already created, the panel's image-save action.
	 * 
	 * @return the action object
	 */
	public Action getPrintAction()
	{
		if (printAction == null)
		{
			printAction = new AbstractAction("Drucken")
			{
				private static final long serialVersionUID = 0L;

				public void actionPerformed(ActionEvent e)
				{
				   	// Get a PrinterJob      
			    	PrinterJob job = PrinterJob.getPrinterJob();      
			    	// Specify the Printable is an instance of SimplePrint2D 
			    	job.setPrintable(ImagePanel.this);      
			    	// Put up the dialog box      
			    	if (job.printDialog())  
			    	{ 	 
			    		// Print the job if the user didn't cancel printing  
			    		try { job.print(); } 	     
			    		catch (Exception ex) { /* handle exception */ }      
			    	}      	
			 
				}
			
			};
		}
		return printAction;
	}


	/* (non-Javadoc)
	 * @see java.awt.print.Printable#print(java.awt.Graphics, java.awt.print.PageFormat, int)
	 */
	public int print(Graphics graphics, PageFormat pageFormat, int pageIndex) throws PrinterException
	{
		if (pageIndex > 0) 
			return Printable.NO_SUCH_PAGE; 
		
		Graphics2D g = (Graphics2D)graphics;
		Dimension  d =   new Dimension(width, height); // getSize();

		Dimension  dprev =  d;  // this.getPreferredSize();
		setSize(dprev);

		// g.setClip((int)pageFormat.getImageableX(), (int)pageFormat.getImageableY(), (int)pageFormat.getImageableWidth(), (int)pageFormat.getImageableHeight());
		g.translate(pageFormat.getImageableX(), pageFormat.getImageableY());
		double scale = Math.min(pageFormat.getImageableWidth() / dprev.width, pageFormat.getImageableHeight() / dprev.height);
		g.scale(scale, scale);

		paint(g);
		// this.setSize(d);
		return Printable.PAGE_EXISTS;
	}

	/**
	 * Save the actual raster image to the given file using the given image-file-format.
	 * No exception is thrown here, but a error-message is printed on system-err.
	 * 
	 * @param file the image-file
	 * @param format the image-file-format (bmp, jpg)
	 */
	public void saveImage(File file, String format)
	{
		System.out.println(getClass().getSimpleName()+".saveImage File="+file+" Format="+format);
		
		// write the rendered Image
		try
		{
			ImageIO.write(getBufferedImage(), format, file);
		} catch (IOException e)
		{
			System.err.println("io error for dest-file '"+file+"': " + e);
		}
	}
	
	private BufferedImage loadImage(File file)
	{
		System.out.println(getClass().getSimpleName()+".loadImage File="+file);
		
		try
		{
			return ImageIO.read(file);
		} catch (IOException e)
		{
			System.err.println("io error for dest-file '"+file+"': " + e);
			return null;
		}
	
	}
	
	public JFileChooser getFileChooser()
	{
		if (fileChooser == null)
		{
			if (parent != null)
				fileChooser = parent.getFileChooser();
			else
			{
				fileChooser = new JFileChooser();
				fileChooser.setFileFilter(new FileNameExtensionFilter( "BMP & JPG Images", "jpg", "bmp"));
				fileChooser.setDialogTitle("Raster-Bild speichern");
			}
		}
		return fileChooser;
	}
	
	public static RenderingHints getRenderingHints()
	{
		RenderingHints renderingHints = 
			new RenderingHints((RenderingHints.Key)defaultRenderingHints[0][0], defaultRenderingHints[0][1]); 
		for (int i=1; i<defaultRenderingHints.length; i++)
			renderingHints.put((RenderingHints.Key)defaultRenderingHints[i][0], defaultRenderingHints[i][1]);
		return renderingHints;
	}

	/**
	 * Access and Initialization to the destination image's buffer <code>BufferedImage</code>
	 * 
	 * @param file, an optional image file to initialize the pixel raster, may be null
	 * @return the initialized buffered image
	 */
	public BufferedImage getBufferedImage(File file)
	{
		if (bufferedImage == null)
		{
			BufferedImage image = null;
			if (file != null)
			{
				image = loadImage(file);
				if (image == null)
					throw new IllegalArgumentException("can't load image '"+file.getPath()+"'");
			} else if (width<0 || height<0)
				throw new IllegalArgumentException("width and height may not be undefined, width="+width+", height="+height);
			
			if (this.width<=0)
				this.width = image.getWidth();
			if (this.height<=0)
				this.height = image.getHeight();

			bufferedImage = new BufferedImage(width, height, bufferedImageType);
			g2d = bufferedImage.createGraphics();
			g2d.setRenderingHints(getRenderingHints());
			g2d.setColor(defaultColor);	
			if (image != null)
				g2d.drawImage(image, 0, 0, width, height, this);
			else
				g2d.drawRect(0, 0, width, height);
		}
		return bufferedImage;
	}
	
	/**
	 * Access and Initialization to the destination image's buffer <code>BufferedImage</code>
	 * 
	 * @return the initialized buffered image
	 * @see <code>getBufferedImage(File f)</code>
	 */
	public BufferedImage getBufferedImage()
	{
		return getBufferedImage((File)null);
	}
	
	/**
	 * Access to the off-Screen Graphics2D object
	 * Do not overload getGraphics() of JComponent.
	 * 
	 * @return the Graphics2D object
	 */
	public Graphics2D getGraphics2D()
	{
		return g2d;
	}
	
	/**
	 * @return the raster width in pixel
	 */
	public int getImageWidth()
	{
		return width;
	}
	
	/**
	 * @return the raster height in pixel
	 */
	public int getImageHeight()
	{
		return height;
	}
	
	/**
	 * Repaint a rectangle region of the off-screen image, given in image-koor.
	 * @param rect, region to repaint in image-koor
	 */
	public void repaintImage(Rectangle rect)
	{
		Dimension d = getSize();
		repaint(rect.x*d.width/width, rect.y*d.height/height, rect.width*d.width/width, rect.height*d.height/height);
	}
		
	/**
	 * @return the graphic's fill color
	 */
	public int getColor()
	{
		return g2d.getColor().getRGB();
	}

	/**
	 * Set the graphic's fill color
	 * @param color
	 */
	public void setColor(int color)
	{
		g2d.setColor(new Color(color));
	}
	
	/**
	 * Fill the raster with the current graphic's foreground color
	 */
	public void clear()
	{
		g2d.fillRect(0, 0, width, height);
	}
	
	/**
	 * Fill a rectangle region of the raster with the current graphic's foreground color
	 * 
	 * @param rect, the rectangle region
	 */
	public void fillRectangle(Rectangle rect)
	{
		g2d.fillRect(rect.x, rect.y, rect.width, rect.height);
	}
	
	/**
	 * Farbe im ARGB-Farbraum für ein pixel an Position (x,y) setzen.
	 * 
	 * @param x, pixel-Koordinate x
	 * @param y, pixel-Koordinate y
	 * @param rgb, 32 bit Farbwert, jeweils 8 bit für (MSB) alpha, red, green, blue
	 */
	public void setRGB(int x, int y, int rgb)
	{
		bufferedImage.setRGB(x, y, rgb);
	}
	
	/**
	 * Farbe im Raster an Position (x,y)
	 * 
	 * @param x
	 * @param y
	 * @return
	 */
	public int getRGB(int x, int y)
	{
		return bufferedImage.getRGB(x, y);
	}
	
	/* (non-Javadoc)
	 * @see javax.swing.JComponent#paintComponent(java.awt.Graphics)
	 */
	protected void paintComponent(Graphics graphic)
	{
		// use the swing's new Graphics2D renderer
		Graphics2D g = (Graphics2D)graphic;
		
		// setup the rendering quality
		g.setRenderingHints(g2d.getRenderingHints());
		// g.setRenderingHints(getRenderingHints());

		// draw the Image
		g.drawImage(bufferedImage, 0, 0, this.getWidth(), this.getHeight(), this);
		
		// draw the selection rect.
		mouseHandler.paintRectangle(graphic, Color.white);
	}
	
	/* (non-Javadoc)
	 * @see javax.swing.JComponent#getPreferredSize()
	 */
	public Dimension getPreferredSize()
	{
		return bufferedImage != null?
				new Dimension(bufferedImage.getWidth(), bufferedImage.getHeight()) :
				new Dimension(700, 450);
	}
	
	//-------------------------------------- Event-Handling
	
	protected void doOnRectangleSelection(Rectangle rect)
	{ }
	
	protected void doOnPopupTrigger(MouseEvent e)
	{ 
		getPopupMenu().show(e.getComponent(), e.getX(), e.getY());
	}
	
	
	
	
		
	public static void main1(String[] args)
	{		
		// arguments and init
		int width = 700, height = 480;
		
		// create the conversion renderer and buffer
		ImagePanel image = new ImagePanel(width, height);
		JFrame f = new JFrame("Raster-Image Viewer");				
		f.setDefaultCloseOperation(javax.swing.JFrame.EXIT_ON_CLOSE);
		f.setContentPane(image);
		f.pack();
		f.setVisible(true);
		
		for (int x=0; x<width; x++)
			for (int y=0; y<height; y++)
			{
				int r = (int)(256 * Math.sqrt((double)(x*x + y*y) / (width*width + height*height))) & 0xFF;
				int g = (x ^ y) & 0xFF;
				int b = (int)(Math.random()*255);
				int a = (x>>>3)%2 == 0 ? 128 : 255;
				
				int argb = (a<<24)|(r<<16)|(g<<8)|b;
				image.setRGB(x, y, argb);
			}
		image.repaint();
	}
	
	public static void main(String[] args)
	{		
		// arguments and init
		int width = 700, height = 480;
		
		int N = 0x8000;  // = 15 bit
		byte[] rd = new byte[N];
		byte[] gr = new byte[N];
		byte[] bl = new byte[N];
		
		for (int i = 0; i < N; i++)
		{
			rd[i] = (byte)(((i>>>10)&0x1F)<<3);
			gr[i] = (byte)(((i>>> 5)&0x1F)<<3);
			bl[i] = (byte)(((i     )&0x1F)<<3);
		}
		
		IndexColorModel colorModel = new IndexColorModel(15, N, rd, gr, bl);
		
		
		// create the conversion renderer and buffer
		ImagePanel image = new ImagePanel(width, height, colorModel, null);
		ImageFrame f = new ImageFrame("Color-Model", image, false);		
		f.setVisible(true);
		
		WritableRaster raster = image.getBufferedImage().getRaster();
		int norm = width*width + height*height;
		
		short[] data = new short[1];
		
		for (int x=0; x<width; x++)
			for (int y=0; y<height; y++)
			{
				data[0] = (short)(N * Math.sqrt((double)(x*x + y*y) / norm));
				raster.setDataElements(x, y, data);
			}
		
		image.repaint();
	}
	
	class RectangleSelectionHandler extends MouseInputAdapter
	{
		private boolean   active = false;
		private Point     startPoint = null;
		private Rectangle currentRect = new Rectangle();
		private Rectangle lastRect = new Rectangle();
		private Component comp;
		
		public RectangleSelectionHandler(Component c)
		{
			comp = c;
		}
		
		public void mousePressed(MouseEvent e)
		{
			// System.out.println(getClass().getSimpleName()+".mousePressed at "+e.getPoint());
	        if (e.isPopupTrigger()) 
	        {
	        	ImagePanel.this.doOnPopupTrigger(e);
	        } else
	        {
	        	startPoint = e.getPoint();
	        	currentRect.setLocation(e.getPoint());
	        	currentRect.setSize(0, 0);
	        	active = true;
	        }
		}

		public void mouseReleased(MouseEvent e)
		{
	        if (e.isPopupTrigger()) 
	        {
	        	ImagePanel.this.doOnPopupTrigger(e);
	        } else
	        {
	        	active = false;
	        	updateSize(e);
	        	Rectangle r = new Rectangle(
	        			currentRect.x * getImageWidth()  / getWidth(),
	        			currentRect.y * getImageHeight() / getHeight(),
	        			currentRect.width  * getImageWidth()  / getWidth(),
	        			currentRect.height * getImageHeight() / getHeight()					
	        	);

	        	ImagePanel.this.doOnRectangleSelection(r);
	        	// firePropertyChange("SelectionRectangle", null, r);
	        }
		}
		
		public void mouseDragged(MouseEvent e)
		{
			updateSize(e);
		}
		
		private void updateSize(MouseEvent e)
		{	
			lastRect.setBounds(currentRect);
			currentRect.x = Math.min(startPoint.x, e.getX());
			currentRect.y = Math.min(startPoint.y, e.getY());
			currentRect.width  = Math.abs(e.getX()-startPoint.x);
			currentRect.height = Math.abs(e.getY()-startPoint.y);
			
			Rectangle rp = lastRect.union(currentRect);
			comp.repaint(rp.x, rp.y, rp.width, rp.height);
		}
		
		public void paintRectangle(Graphics g, Color color)
		{
			if (!active || currentRect.width <= 0 || currentRect.height <= 0)
				return;
			Color tmp = g.getColor();
			g.setColor(color);
			g.drawRect(currentRect.x, currentRect.y, currentRect.width-1, currentRect.height-1);
			g.setColor(tmp);
		}
		
	}


	public void windowActivated(WindowEvent e)
	{
	}

	public void windowClosed(WindowEvent e)
	{
		dispose();
		System.runFinalization();
	}

	public void windowClosing(WindowEvent e)
	{
	}

	public void windowDeactivated(WindowEvent e)
	{
	}

	public void windowDeiconified(WindowEvent e)
	{
	}

	public void windowIconified(WindowEvent e)
	{
	}

	public void windowOpened(WindowEvent e)
	{
	}
}
```


----------



## faetzminator (6. Dez 2009)

Probiers mal so:

```
public int getAverageColor(ImageFrame f) {
	BigInteger[] color = getBigIntegers(3);
	for (int y = 0; y < f.getImageHeight(); y++) {
		for (int x = 0; x < f.getImageWidth(); x++) {
			int c = f.getRGB(x, y);
			color[0] = add(color[0], (c >> 16) & 0xFF);
			color[1] = add(color[1], (c >> 8) & 0xFF);
			color[2] = add(color[2], c & 0xFF);
		}
	}
	BigInteger size = new BigInteger(String.valueOf(f.getImageHeight()));
	size = size.multiply(new BigInteger(String.valueOf(f.getImageWidth())));
	for (int i = 0; i < color.length; i++) {
		color[i] = color[i].divide(size);
	}
	return (0xFF << 24) | (color[0].intValue() << 16)
			| (color[1].intValue() << 8) | color[2].intValue();
}

private BigInteger add(BigInteger bi, long l) {
	return bi.add(new BigInteger(String.valueOf(l)));
}

private BigInteger[] getBigIntegers(int size) {
	BigInteger[] bigIntegers = new BigInteger[size];
	for (int i = 0; i < bigIntegers.length; i++) {
		bigIntegers[i] = new BigInteger("0");
	}
	return bigIntegers;
}
```

Edit:
1. Code ist ungetestet
2. Ich verwende [c]BigInteger[/c] statt [c]int[/c], weil zwischenzeitlich [c]Integer.MAX_VALUE ^ 3[/c] in den Variablen vorkommen könnte.


----------



## Wirtschaftsingenieur (6. Dez 2009)

Danke.
Ich habe noch eine Frage. Wie kann ich ein Bild drehen?
Als wir haben das in der Uni immer so gemacht

```
// Laden einer bestehenden Bilddatei
ImageFrame f = new ImageFrame(new File("src/beham/plot/images/maske.gif"), "Name des Bildes"); f.setVisible (true);
// Neues Bild "f1" erzeugen und Bildinhalt von "f" reinkopieren
ImageFrame f1 = new ImageFrame(f.getImageWidth(), f.getImageHeight(), "Name des neuen Bildes");
for (int y = 0; y<f.getImageHeight(); y++)
for (int x = 0; x<f.getImageWidth(); x++)
{
f1.setRGB(x, y, f.getRGB(x, y));
}
// Bild "f" um 180° drehen und in den frame "f3" reinschreiben
for (int y = 0; y < f1.getImageHeight(); y++)
for (int x = 0; x < f1.getImageWidth(); x++)
{
f1.setRGB(x, y, f.getRGB(f.getImageWidth()-x, f.getImageHeight()-y));
}
f1.setVisible(true);
```
Wie kann ich einen Code schreiben, der ein Bild zum Beispiel um 220° dreht?


----------



## faetzminator (6. Dez 2009)

Da bräuchte es viel Mathematik / Geometrie  Aber es würde sicher eine API geben, welche das kann.


----------



## Marco13 (6. Dez 2009)

Statt BigInteger würde es vermutlich auch ein long tun...

Das drehen um 220° wäre ein Dreizeiler, wenn man NUR BufferedImages verwenden würde (vermutlich würde es auch mit den gegebenen Klassen recht einfach gehen, aber dazu müßte man (ich) die erstmal nachvollziehen (wollen)). Aber mit BufferedImages würde es etwa so gehen:

```
BufferedImage input = ...
BufferedImage rotated = ...
Graphics2D g = rotated.createGraphics();
g.rotate(angleRadians, pointX, pointY);
g.drawImage(input,0,0,null);
g.dispose();
```
Kannst ja mal schauen, ob du das in das ImagePanel irgendwo einbauen kannst....


----------



## Wirtschaftsingenieur (7. Dez 2009)

Ich hab noch ein Problem. Wie kann ich einstellen, dass ich ein Bild nur in Blau-stufen oder Grünstufen anzeigen will?
Das folgende Programm erstellt NegativFarben:

```
Bestehende Bilddatei laden
		ImageFrame f = new ImageFrame(new File ("src/xy/plot/images/sundown.jpg"), "Sonnenuntergang Original");
		f.setVisible(true);
		// Neues Bild erzeugen
		ImageFrame f1 = new ImageFrame(f.getWidth(), f.getHeight(), "Sonnenuntergang Neu");
		for (int y = 0; y<f.getImageHeight(); y++)
			for (int x = 0; x<f.getImageWidth(); x++)
			{
				f1.setRGB(x, y, f.getRGB(x, y));
			}
		for (int y = 0; y < f1.getImageWidth(); y++)
		{
			for (int x = 0; x < f1.getImageWidth(); x++)
			{
				// Lese RGB-Farbwert
				int color = f1.getRGB(x, y);
				//Zerlegen RGB in die drei Farbintensitäten
				int r = (color >> 16) & 0xFF;
				int g = (color >> 8) & 0xFF;
				int b = color & 0xFF;
				// Negativ Farben bilden
				r = 255 - r;
				g = 255 - g;
				b = 255;
				color = (0xFF<<24)| (r<<16) | (g<<8)| b;
				f1.setRGB(x, y, color);
			}
		}
		f1.setVisible(true);
```
Wenn ich zum Beispiel will, dass es in grau angezeigt wird, muss ich r, g und b gleichsetzen. Aber wie ist das bei den anderen Farben? Welche Zahl muss ich bei //Negativ Farben bilden eingeben, damit es zum Beispiel grün oder blau angezeigt wird.


----------



## faetzminator (7. Dez 2009)

Ich würde versuchen, die gewünschte Farbe prozentual zu erhöhen und die anderen Farbwerte prozentual zu verringern. Bei einem Wert, welcher in RGB enthalten ist, ist das relativ simpel. Betrifft es zwei oder drei der Werte, muss wieder der jeweilige prozentuale Wert verwendet werden. Beispiel: Sagen wir, jede Farbe (R, G und B), welche zu 0% in dem gewünschten Stich vorkommt, wird um 10% verringert und jede Farbe, welche zu 100% vorkommt, soll um 20% erhöht werden. Teilt sich z.B. Rot und Blau dies 50:50, ergibt das +5% und -10% für die letztere Farbe. Die genauen Werte müsste man erproben.


----------



## Marco13 (7. Dez 2009)

Wenn du nur den blau- oder grün_anteil_ anzeigen willst, einfach

```
r = 255 - r;
g = 255 - g;
b = 255;
```
ändern in

```
r = 0;
g = 0;
```
bzw

```
r = 0;
b = 0;
```


Ansonsten müßtest du genauer sagen, was du willst...


----------



## faetzminator (7. Dez 2009)

Grünstich heisst doch nicht, dass alle anderen Farben komplett auf 0 gesetzt werden?


			
				http://de.wikipedia.org/wiki/Farbstich hat gesagt.:
			
		

> Unter Farbstich versteht man in der Farblehre eine Farbnuance, eine Verschiebung einer Farbe zu einer anderen Farbvalenz. Der Begriff ist in der DIN 55980 definiert.


----------



## Marco13 (8. Dez 2009)

Der TO hat nur gesagt, dass er "ein Bild nur in Blau-stufen oder Grünstufen anzeigen" will, ich habe gesagt, was er machen muss, wenn er "nur den blau- oder grünanteil anzeigen will" - und dass er genauer sagen soll, was er meint, wenn es das nicht war. Von "Stich" war eigentlich nicht die Rede. Aber gut zu wissen, dass selbst so ein Begriff eine Definition hat


----------



## faetzminator (8. Dez 2009)

Ups, da habe ich wohl die Aufgabe falsch verstanden. Aber das könnte man natürlich trotzdem mit meinem Ansatz lösen, da wär einfach Farbanteil: +0%; alles andere: -100%  Bei "Mischfarben" natürlich wieder ein prozentual errechneter Teil. Btw.: schön gibts Wikipedia


----------

