Thursday 14 May 2015

Filtering Images (RGBImageFilter) in Java



Image filters provide an easy way to transform images. The RGBImageFilter makes it easy to execute transformations that only require information about the pixel being modified. Although that excludes a wide range of common transformations, it does support a large number, such as converting to grayscale, image fade out, and color separation. The applet in Listing 17.34 takes an image, inverts all the colors, and then displays the before and after pictures

Listing 17.34. Using an RGBImageFilter.
import java.applet.Applet;
import java.awt.*;
import java.awt.image.*;


public class rgbimagefilter extends Applet implements  Runnable{
    Image the_picture, filtered_image;
    boolean image_ready;
    Thread the_thread;
    MediaTracker the_tracker;
    //Sep is the new class that extends RGBImageFilter
    Sep image_filter;

    public void start() {
        if (the_thread == null) {
            the_thread = new Thread(this);
            the_thread.start();
        }
    }
    public void stop() {
        the_thread.stop();
    }

    public void run() {

        the_thread.setPriority(Thread.MIN_PRIORITY);
        while (true) {
            repaint();
            try {
                the_thread.sleep(3000);
            } catch(InterruptedException e) {};
        }
    }
    public void init()
    {
        the_tracker = new MediaTracker(this);
        image_ready = false;
        the_picture = getImage(getDocumentBase(),"test.gif");
        the_tracker.addImage(the_picture,0);
        //modify the image and track the process
        filter_image();
        the_tracker.addImage(filtered_image,1);

    }
    public void filter_image() {
        image_filter = new Sep();
        //create the new filtered image using the getSource method on the input
        //picture as a pixel producer
        filtered_image = createImage(new FilteredImageSource
                            (the_picture.getSource(),image_filter));
    }
    public void paint(Graphics g)
    {
        //wait for both images to be loaded before drawing them
        if(the_tracker.checkID(0,true) &
                                the_tracker.checkID(1,true)) {
            image_ready = true;
            g.drawImage(the_picture,0,0,this);
            g.drawImage(filtered_image,60,60,this);
        } else {
            System.out.println("Waiting for image to fully load");
        }
    }
}

class Sep extends RGBImageFilter{

    public Sep() {
        //This specifies that this class can work with IndexColorModel where
        //each pixel contains a pointer to a color in a lookup table rather than
        //a 32 bit color
        canFilterIndexColorModel = true;
    }

    public int filterRGB(int x, int y, int rgb) {
        int blue,red,green,new_color;

        //get the three color components from the rgb int
        blue = rgb & 0x000000FF;
        green = (rgb & 0x0000FF00) >> 8;
        red = (rgb & 0x00FF0000) >> 16;
        //These three lines invert the color
        blue = 255 - blue;
        green = 255 - green;
        red = 255 - red;
        //create the new color and then get the int version of the color
        new_color = (new Color(red,blue,green)).getRGB();
        return new_color;
    }
}


All the work is done in the filterRGB method, which is called for each pixel or every color in the lookup table for indexed color models. You can put any algorithm in that method that only requires information about that one color and/or pixel. If your transformation is position dependent (it's a function of x and/or y), you can't work with an indexed color model because the filterRGB method, in this case, is called only for the colors in the lookup table-not for every pixel.  

No comments:

Post a Comment