Home : Course Map : Chapter 11 : Java : Supplements :
Rescaling and ColorConvert Filters
JavaTech
Course Map
Chapter 11

Introduction
Image Class
Image Loading
  Demo 1 Demo 2  
Pixels/Transparency
  Demo 3
Pixel Handling
  Demo 4  
Demo 5
Exercises

    Supplements
Java 2D Imaging
BufferedImage
Creating Buf.Image
Pixel Handling
  Demo 1 Demo 2
Filters
  Convolutions
     Demo 3
  AffineTransforms
     Demo 4
  LookupTable
     Demo 5 Demo 6
  Rescale
     Demo 7
  Color Conversion
     Demo 8
  Custom
     Demo 9
Exercises
Java Adv Imaging
AWT Flicker:
  Override Update
     Demo 1  Demo 2
  Clipping
     Demo 3
  Double Buffer
     Demo 4

     About JavaTech
     Codes List
     Exercises
     Feedback
     References
     Resources
     Tips
     Topic Index
     Course Guide
     What's New

The RescaleOp filter applies a scaling factor and an offset to each color components so as to brighten or dim an image:

 destColor = sourceColor * scalefactor + offset

You could do this also with a look up table but you need less code with this filter. For example,

 RescaleOp brightenOp = new RescaleOp(2.0f, 32f, null);
 BufferedImage dest_image = brightenOp.filter(sourceImage, null);

Here each color component of each pixel is multiplied by 2.0 and then added to 32. If the value exceeds the maximum for that component, the maximum is used.

In the RescaleApplet example below, we use the RescaleOp filter to multiply the color component values with a scaling factor and also add an offset value. The user selects the scaling and offset via two sliders.

RescaleApplet
Resources: saturnVoyager.jpg

import javax.swing.*;
import java.awt.*;
import java.awt.image.*;
import javax.swing.event.*;

/** Demonstrate the rescale filter. **/
public class RescaleApplet extends JApplet
                          implements ChangeListener {

  BufferedImage fSrcImage, fDstImage;
  ImageIcon fDstIcon;
  JLabel fRescaleLabel, fOffsetLabel;
  JSlider fRescaleSlider,fOffsetSlider;
  float fScaleFactor = 1.0f;
  float fOffset = 1.0f;

  /**
    * Build the interface with the source and filter output image
    * displayed side by side.
   **/
  public void init () {

    setLayout (new BorderLayout ());

    fSrcImage = getBufImage ("saturnVoyager.jpg");
    if (fSrcImage == null) {
        System.out.println ("Error in reading image file!");
        return;
    }

    JPanel control_panel = new JPanel(new GridLayout (2,1));
    control_panel.add (fRescaleLabel =
                       new JLabel ("Scale factor 1 ",SwingConstants.RIGHT) );
    control_panel.add (fRescaleSlider =
                       new JSlider (Adjustable.HORIZONTAL, 0, 255, 1));
    fRescaleSlider.addChangeListener (this);

    control_panel.add (fOffsetLabel =
                       new JLabel ("Offset 0 ",SwingConstants.RIGHT) );
    control_panel.add (fOffsetSlider =
                       new JSlider (Adjustable.HORIZONTAL, 0, 255, 0));
    fOffsetSlider.addChangeListener (this);

    // Rescale with default scale and offset values.
    rescaleFilter();

    // Use ImageIcon objects to hold the two images
    ImageIcon src_icon = new ImageIcon (fSrcImage);
    fDstIcon = new ImageIcon (fDstImage);

    // Put the icons on labels
    JLabel src_display = new JLabel (src_icon);
    JLabel dst_display = new JLabel (fDstIcon);

    // And then display the labels on the scroll panes
    JScrollPane src_pane = new JScrollPane (src_display);
    JScrollPane dst_pane = new JScrollPane (dst_display);

    // Use a JSplitPane to show the source and destination
    // images side by side.
    JSplitPane split_pane =
      new JSplitPane (JSplitPane.HORIZONTAL_SPLIT, true, src_pane, dst_pane);

    split_pane.setResizeWeight (0.5);
    split_pane.setContinuousLayout (true);

    // Add the DrawingPanel to the contentPane.
    add (split_pane, BorderLayout.CENTER);
    add (control_panel, BorderLayout.SOUTH);

  } // init

  /**
    * This class implements ChangeListener for the
    * slider. So the ChangeEvents come here when the
    * slider is moved.
   **/
  public void stateChanged (ChangeEvent evt) {

    // Use the label to show the numerical value of the slider.
    fRescaleLabel.setText ("Scale factor " +
                       Integer.toHexString (fRescaleSlider.getValue ()));

    // Get the values from the slider and set a new scale factor.
    fScaleFactor = fRescaleSlider.getValue ();

    // Use the label to show the numerical value of the slider.
    fOffsetLabel.setText ("Offset " +
                       Integer.toHexString (fOffsetSlider.getValue ()));

    // Get the values from the slider and set a new scale factor.
    fOffset = fOffsetSlider.getValue ();

    // Rescale with latest scale and offset values.
    rescaleFilter();

    // Reset the destination images with the modified version.
    fDstIcon.setImage(fDstImage);

    // Repaint to show the modified image.
    repaint ();

  } // stateChanged

  /** Create the filter to execute a threshold setting on the
    * color component values.
   **/
  void rescaleFilter () {

      RescaleOp brighten_op = new RescaleOp (fScaleFactor, fOffset, null);
      fDstImage =  brighten_op.filter (fSrcImage, null);

  } // rescaleFilter


  /**
   *  Download the image file and convert to a
   *  BufferedImage object.
   */
  BufferedImage getBufImage (String image_name){

    // Get the image
    Image img = getImage (getCodeBase(), image_name);

    // and use a MediaTracker to load it before converting it to
    // a BufferedImage.
    try {
      MediaTracker tracker = new MediaTracker (this);
      tracker.addImage (img,0);
      tracker.waitForID (0);
    } catch (InterruptedException e) { return null; }

    int width = img.getWidth (this);
    int height= img.getHeight (this);

    BufferedImage buffered_image =
      new BufferedImage (width, height, BufferedImage.TYPE_INT_RGB);
    Graphics2D g2 = buffered_image.createGraphics ();
    g2.drawImage (img,0 ,0, null);

    return buffered_image;

  } // getBufImage

} // class RescaleApplet

 

Color Conversion

The ColorConvertOp filter changes an image from one color space to another. A common requirement in image processing is to change to gray scale. The following code shows how to create such a color to gray conversion:

  ColorSpace gray_space =
     ColorSpace.getInstance (ColorSpace.CS_GRAY);
  ColorConvertOp convertToGrayOp = new ColorConvertOp ( gray_space, null);
  BufferedImage gray_image = convertToGrayOp.filter (source_image, null);

Besides RGB and gray, the java.awt.color.ColorSpace class offers a number of options for color spaces including CMYK and HSV.

The ColorConvertApplet program below applies the ColorConvertOp to a source image to convert it to gray scale.

ColorConvertApplet
Resources: saturnVoyager.jpg

import javax.swing.*;
import java.awt.*;
import java.awt.image.*;
import javax.swing.event.*;
import java.awt.color.*;

/** Demonstrate a color conversion filter. **/
public class ColorConvertApplet extends JApplet {

  BufferedImage fSrcImage, fDstImage;
  ImageIcon fDstIcon;

  /**
    * Build the interface with the source and filter output image
    * displayed side by side.
   **/
  public void init () {

    fSrcImage = getBufImage ("saturnVoyager.jpg");
    if (fSrcImage == null) {
        System.out.println ("Error in reading image file!");
        return;
    }

    // Convert to gray scale.
    convertFilter();

    // Use ImageIcon objects to hold the two images
    ImageIcon src_icon = new ImageIcon (fSrcImage);
    fDstIcon = new ImageIcon (fDstImage);

    // Put the icons on labels
    JLabel src_display = new JLabel (src_icon);
    JLabel dst_display = new JLabel (fDstIcon);

    // And then display the labels on the scroll panes
    JScrollPane src_pane = new JScrollPane (src_display);
    JScrollPane dst_pane = new JScrollPane (dst_display);

    // Use a JSplitPane to show the source and destination
    // images side by side.
    JSplitPane split_pane =
      new JSplitPane (JSplitPane.HORIZONTAL_SPLIT,
                      true, src_pane, dst_pane);

    split_pane.setResizeWeight (0.5);
    split_pane.setContinuousLayout (true);

    // Add the DrawingPanel to the contentPane.
    add (split_pane);

  } // init


  /** Use ColorConvertOp to convert the source image to gray scale  **/
  void convertFilter () {

    ColorSpace gray_space =
      ColorSpace.getInstance (ColorSpace.CS_GRAY);
    ColorConvertOp convert_to_gray_op =
      new ColorConvertOp (gray_space, null);
    fDstImage = convert_to_gray_op.filter (fSrcImage, null);

  } // rescaleFilter


  /**
   *  Download the image file and convert to a
   *  BufferedImage object.
   */
  BufferedImage getBufImage (String image_name){

    // Get the image
    Image img = getImage (getCodeBase(), image_name);

    // and use a MediaTracker to load it before converting it to
    // a BufferedImage.
    try {
      MediaTracker tracker = new MediaTracker (this);
      tracker.addImage (img,0);
      tracker.waitForID (0);
    } catch (InterruptedException e) { return null; }

    int width = img.getWidth (this);
    int height= img.getHeight (this);

    BufferedImage buffered_image =
      new BufferedImage (width, height, BufferedImage.TYPE_INT_RGB);
    Graphics2D g2 = buffered_image.createGraphics ();
    g2.drawImage (img,0 ,0, null);

    return buffered_image;

  } // getBufImage

} // class ColorConvertApplet


References & Web Resources

 

Latest update: March 8, 2006

              Tech
Fractals
Fractal Drawing
   Demo 1
Fractal Draw Code
Fractal Images
  Demo 2
Image Processing
  Demo 3
Histogram Image
  Demo 4
Exercises

           Physics
Calibration/SysError
SimWithCal/SysErr
  Demo 1
Analysis
  Demo 2
Examples

Exercises

  Part I Part II Part III
Java Core 1  2  3  4  5  6  7  8  9  10  11  12 13 14 15 16 17
18 19 20
21
22 23 24
Supplements

1  2  3  4  5  6  7  8  9  10  11  12

Tech 1  2  3  4  5  6  7  8  9  10  11  12
Physics 1  2  3  4  5  6  7  8  9  10  11  12

Java is a trademark of Sun Microsystems, Inc.