ImageFilter liegen zwischen Produzenten und Konsumenten und verändern Bildinformationen oder nehmen Einfluss auf die Größe. Für Bild-Produzenten treten die Filter als Konsumenten auf, die die Schnittstelle ImageConsumer implementieren und die wichtige Methode setPixel() programmieren.
Grundlegende Eigenschaft von Filtern
Um einen Filter anzuwenden, nutzen wir die Klasse FilteredImageSource. Im Konstruktor geben wir das Bild und den Filter an. Anschließend können wir den zurückgegebenen Produzenten an createImage() übergeben, und wir haben ein neues Bild.
Beispiel: Anwendung eines Filters:
Image src = getImage( "gatesInAlbuquerque.jpg" ); ImageFilter colorfilter = new GrayFilter(); ImageProducer imageprod = new FilteredImageSource( src.getSource(), colorfilter ); Image img = createImage( imageprod );
Konkrete Filterklassen
Es gibt einige Unterklassen der Klasse ImageFilter, die für unsere Arbeit interessant sind:
Beispiel: Ein Filter, der den Rot- und Blauanteil in einem Bild vertauscht.
class RedBlueSwapFilter extends RGBImageFilter { public RedBlueSwapFilter() { canFilterIndexColorModel = true; } public int filterRGB( int x, int y, int rgb ) { return ( (rgb & 0xff00ff00) | ((rgb & 0xff0000) >> 16) | ((rgb & 0xff) << 16)); } }
Mit CropImageFilter Teile ausschneiden
Mit CropImageFilter lassen sich Teile des Bilds ausschneiden. Wir definieren dafür vom Bild einen Ausschnitt mit den Koordinaten x, y und der Breite und Höhe. Wie die anderen Bildfilter, so wird auch CropImageFilter mit dem FilteredImageSource als Produzent verwendet.
Beispiel Erzeuge für die Grafik big.gif in einem Applet ein neues Image-Objekt. Das Original hat die Größe 100 × 100 Pixel. Das neue Bild soll einen Rand von 10 Pixeln haben.
Image origImage = getImage( getDocumentBase(), "big.gif" ); ImageFilter cropFilter = new CropImageFilter( 10, 10, 90, 90 ); Image cropImage = createImage( new FilteredImageSource(origImage.getSource(),cropFilter) );
Bildausschnitte über PixelGrabber ausschneiden
Nicht nur über CropImageFilter lassen sich Bildausschnitte auswählen. Eine andere Lösung geht über PixelGrabber, da dieser auch einen Ausschnitt erlaubt. Darüber lässt sich dann mit MemoryImageSource wieder ein neues Bild erzeugen.
Beispiel: Schneide aus dem Image img das passende Rechteck mit den Startkoordinaten x, y und der Breite width und der Höhe height aus:
int[] pix = new int[width * height]; PixelGrabber pg = new PixelGrabber( img, x, y, width, height, pix, 0, width ); try { pg.grabPixels(); } catch( InterruptedException e ) {} newImg = createImage(new MemoryImageSource(width, height, pix, 0, width) );
An dieser Stelle sollten wir noch einmal den Unterschied zwischen den beiden Möglichkeiten betonen. PixelGrabber implementiert die Schnittstelle ImageConsumer, sodass er ein Bildkonsument ist und Daten in einem Integer-Feld ablegt. CropImageFilter ist ein Filter, der ein anderes Image-Objekt konstruiert und kein Feld.
Transparenz
Um eine bestimmte Farbe eines Bilds durchsichtig zu machen (also die Transparenz zu bestimmen), nutzen wir einen RGBImageFilter. Dabei implementieren wir einen Konstruktor, der die Farbe sichert, die transparent werden soll. Sie wird später in der Implementierung von filterRGB() verwendet. Die Methode, die ja für jeden Bildpunkt aufgerufen wird, liefert dann entweder die Farbe ohne Alpha-Kanal zurück (rgb|0xff000000) oder eben nur den Alpha-Kanal (rgb & 0xffffff) für Transparenz. Eine interessante Erweiterung ist die Einführung einer Toleranzauswertung um einen »Zauberstab«, der ähnlich wie in Photoshop zu realisieren ist.
import java.awt.*; import java.awt.image.*; public class TransparentFilter extends RGBImageFilter { private final int transparentRGB; public TransparentFilter( Color color ) { this.transparentRGB = color.getRGB(); } @Override public int filterRGB( int x, int y, int rgb ) { if ( rgb != transparentRGB ) return rgb | 0xff000000; return rgb & 0xffffff; //transparent } }