Bildfilter mit AWT-ImageFilter

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:

  • BufferedImageFilter. Diesem Filter lässt sich ein Objekt vom Typ BufferedImageOp übergeben, mit dem unterschiedliche Manipulationen ermöglicht werden. BufferedImageOp ist eine Schnittstelle, die von AffineTransformOp, ConvolveOp, BandCombineOp und LookupOp implementiert wird. AffineTransformOp ist am attraktivsten, da es mit einem AffineTransform konstruiert wird, sodass leicht Vergrößerungen oder Rotationen ermöglicht werden. Über AffineTransform-Objekte erfahren wir im 2D-Abschnitt mehr.
  • CropImageFilter. Bildteile werden herausgeschnitten.
  • ReplicateScaleFilter. Zum Vergrößern oder Verkleinern von Bildern. Ein einfacher Algorithmus wird angewendet. Eine weiche Vergrößerung oder Verkleinerung lässt sich mit der Unterklasse AreaAveragingScaleFilter erreichen.
  • RGBImageFilter. Dieser allgemeine Filter ist für die eigene Filterklasse gedacht. Wir müssen lediglich eine filterRGB()-Methode angeben, die die RGB-Bildinformationen für jeden Punkt (x,y) modifiziert. Benötigt der Filter auch die Nachbarpunkte, können wir nicht mit RGBImageFilter arbeiten.
  • 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
     }
    }

    Ähnliche Beiträge

    Schreibe einen Kommentar

    Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert