Weitere aktuelle Java-Titel finden Sie bei dpunkt.
 Inhaltsverzeichnis   Auf Ebene Zurück   Seite Zurück   Seite Vor   Auf Ebene Vor   Eine Ebene höher   Index


12.9.3

Mehrfache Filterung


Wenn man mehrere Filter hintereinander auf ein Bild anwenden will, sollte man eine Besonderheit des Filtervorgangs beachten.

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.

Diesen Effekt kann man mit Hilfe der Klassen PixelGrabber und MemoryImageSource umgehen. Statt direkt das über die FilteredImageSource erzeugte Bild zu zeichnen, wendet man zunächst einen PixelGrabber auf das gefilterte Bild an. Die Bilddaten werden nämlich noch nicht beim Aufruf von createImage() gefiltert, sondern erst, wenn sie von einem ImageConsumer angefordert werden.

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.

Bei der direkten Benutzung von FilteredImageSource werden die Bilddaten hingegen nicht zwischengespeichert. Deshalb muss bei jedem Zugriff auf die Bilddaten erneut der Filter durchlaufen werden.


 Inhaltsverzeichnis   Auf Ebene Zurück   Seite Zurück   Seite Vor   Auf Ebene Vor   Eine Ebene höher   Index

Copyright © 2002 dpunkt.Verlag, Heidelberg. Alle Rechte vorbehalten.