Bei Durchführung einer Filterung wird mit Hilfe der Methode createImage()
und FilteredImageSource ein neues Image-Exemplar erzeugt:
Image img;
img = createImage(new FilteredImageSource(
picture.getSource(), new BlurFilter()));
picture ist hier ein Exemplar der Klasse Image.
Will der Benutzer nun einen zweiten Filter auf das zuvor gefilterte Bild anwenden,
dann wird erneut über obige createImage()-Methode ein neues
Image-Objekt erzeugt:
Image img;
img = createImage(new FilteredImageSource(
picture.getSource(), new BlurFilter()));
img = createImage(new FilteredImageSource(
img.getSource(), new BlurFilter()));
BlurFilter wird in diesem Fall zunächst auf picture
angewendet und das Ergebnis in img gespeichert.
Danach erfolgt eine nochmalige Anwendung von BlurFilter auf img.
Das Problem bei dieser geschachtelten Anwendung von Filtern besteht darin, dass bei
jedem Zugriff auf die Bilddaten alle Daten vom ImageProducer durch die Filter
zum ImageConsumer geliefert werden müssen. Die Bilddaten müssen dadurch unter
Umständen
den Filter mehrfach durchlaufen, obwohl ein Durchlauf ausreichen würde.
Das wirkt sich besonders bei rechenintensiven Filtern negativ auf die Performance aus.
In obigem Beispiel würde der erste Filterdurchlauf stattfinden,
wenn das einfach gefilterte Bild gezeichnet wird.
Wendet man den Filter nun auf das einfach gefilterte Bild an, wird beim Zeichnen des neuen
Bildes sowohl der Filter für die erste Filterung als auch der Filter für die zweite
Filterung durchlaufen. Bei zweifacher Anwendung desselben Filters entsteht so
für die zweite Filterung die doppelte Laufzeit.
PixelGrabber ist ein ImageConsumer, der bei Aufruf dessen Methode
grab()
die Bilddaten vom ImageProducer anfordert. Dadurch wird der Filtervorgang ausgeführt,
und die Bilddaten sind anschließend in einem Array verfügbar.
Aus den Bilddaten, die der PixelGrabber liefert, kann man über
MemoryImageSource und createImage() ein neues Bild erzeugen:
PixelGrabber grabber =
new PixelGrabber(img, 0, 0, width, height,
pix, 0, width);
try {
grabber.grabPixels();
}
catch (InterruptedException e) {}
MemoryImageSource memImg =
new MemoryImageSource( width, height, pix, 0, width);
img = createImage(memImg);
Durch die Zwischenschaltung von PixelGrabber und MemoryImageSource zwischen
die einzelnen Filtervorgänge werden geschachtelte Filter vermieden.
Die Bildfilterung wird über den PixelGrabber durchgeführt und anschließend die gefilterten
Bilddaten in einem Array »konserviert«. Aus diesem Array kann man mit MemoryImageSource
ein neues Image-Exemplar erzeugen.