Home : Course Map : Chapter 11 : Java :
Pixel Handling
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

Images can also be created from scratch by creating, loading and accessing pixel arrays. The 32-bit pixel arrays typically use an ARGB color model discussed previously. Below we show

Creating an Image from a Pixel Array

MemoryImageSource is a convenient class for creating images directly from pixel arrays and for doing simple animations. Below we show the example program CreateImageApplet and the JPanel subclassImagePanel, which is displayed on the applet. An image is created and displayed on the panel.

In the init() method in the ImagePanel class, an array large enough to hold the pixels for the applet's panel is created with :

    fWidth  = getSize ().width;
    fHeight = getSize ().height;
    fPixels = new int [fWidth * fHeight];

Then two loops fill the pixels with a spectrum of red, green, and blue values plus an opaque alpha value (255).

fPixels[i++] =  (alpha << 24) |  (red << 16)
                        |  (green << 8 ) | blue;

We then use the createImage(ImageProducer producer) method in the Component class to create the image. The MemoryImageSource implements the ImageProducer interface and its constructor takes the pixel array as follows:

    fImage = createImage (
        new MemoryImageSource (fWidth, fHeight, fPixels, 0, fWidth));

The first three arguments in the MemoryImageSource constructor are the width and height of the image and the pixel array. The fourth argument is the offset into the array where the data begins and in this case is simply 0. The last argument is the length of the scan line in the pixel array that corresponds to the horizontal line in the image and in this case is simply the width of the panel.

CreateImageApplet.java

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

/** Create an image from a pixel array. **/
public class CreateImageApplet extends JApplet
{
  ImagePanel fImagePanel;

  public void init () {
    Container content_pane = getContentPane ();

    // Create an instance of ImagePanel
    fImagePanel = new ImagePanel ();

    // Add the ImagePanel to the contentPane.
    content_pane.add (fImagePanel);
    
  } // init

  // Tell the panel to create and display the image.
  public void start () {
    fImagePanel.init ();
  }

} // class CreateImageApplet

/** Create an image from a pixel array. **/
class ImagePanel extends JPanel
{
  Image fImage;
  int fWidth = 0, fHeight = 0;
  int [] fPixels;

  /**
    * Create an image from a pixel array and MemoryImageSource.
    *
    * Do the image building in this method rather
    * than in a constructor so that it will know
    * the size of the panel after it has been added
    * to the applet.
   **/
  void init () {
    fWidth  = getSize ().width;
    fHeight = getSize ().height;
    fPixels = new int [fWidth * fHeight];

    int i=0;
    int half_width = fWidth/2;

    // Build the array of pixels with the color components.
    for  (int y = 0; y < fHeight; y++) {
      for ( int x = 0; x < fWidth; x++) {
        // Start red on left and decrease to zero at center
        int red = 255 -  (512 * x)/fWidth;
        if (red < 0 ) red = 0;

        // Green peaks in center
        int green;
        if (x < half_width )
            green =  (512 * x)/fWidth;
        else
          green = 255 -  (255 *  (x - half_width))/half_width;

        // Blue starts from center and peaks at right side.
        int blue = 0;
        if (x > half_width)
            blue =  (255 *  (x - half_width))/half_width;

        int alpha = 255; // non-transparent
        fPixels[i++] =  (alpha << 24) |  (red << 16)
                        |  (green << 8 ) | blue;
      }
    }
    // Now create the image from the pixel array.
    fImage = createImage (
        new MemoryImageSource (fWidth, fHeight, fPixels, 0, fWidth));
  } // init

  /** Paint the image on the panel. **/
  public void paintComponent (Graphics g) {
    super.paintComponent (g);
    g.drawImage (fImage, 0, 0, this );
  }

} // class ImagePanel

 

 

Creating an Animation from a Pixel Array

MemoryImageSource can also provide an animation as shown below with the example program AnimationApplet . By invoking the setAnimate(true) method, the MemoryImageSource object will respond to an invocation of the newPixels() method by repainting the image.

AnimationApplet implements Runnable and a loop in the run() method periodically invokes the newFrame() method in the DrawingPanel object, which is displayed on the applet. This method shifts the color components in the pixel array and then invokes the method newPixels (0, 0, fWidth, fHeight) for the MemoryImageSource object. This will cause the image to be repainted and thus create an animated effect.

AnimationApplet.java

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

/** Use MemoryImageSource to create an animated image. **/
public class AnimationApplet extends JApplet
                       implements Runnable
{
  // Will use thread reference as a flag
  Thread fThread;
  //msecs of sleep time
  int fDeltaT = 10;
  // Need a reference to the panel on which animation appears
  DrawingPanel fDrawingPanel;

  /** Create a simple interface to draw the animation.**/
  public void init () {
    Container content_pane = getContentPane ();

    // Create an instance of DrawingPanel
    fDrawingPanel = new DrawingPanel ();

    // Add the DrawingPanel to the contentPane.
    content_pane.add (fDrawingPanel);
  } // init

  /** Start the thread that controls the animation.**/
  public void start () {
    // Tell the panel to create the image source.
    fDrawingPanel.init ();

    // If the thread reference not null then a
    // thread is already running. Otherwise, create
    // a thread and start it.
    if (fThread == null) {
        fThread = new Thread (this);
        fThread.start ();
    }
  } // start

  /** Stop thread by setting flag. **/
  public void stop () {
     fThread = null;
  }

  public void run () {

    // Loop through sleep periods until flag set to null
    while (fThread != null) {
      try  {
        Thread.sleep (fDeltaT);
      } catch  (InterruptedException e) {}
      // Send request for create new image
      fDrawingPanel.newFrame ();
    }
  } // run

} //class AnimationApplet

/** Display the animation on this panel. **/
class DrawingPanel extends JPanel
{
  Image fImage;
  int fWidth, fHeight;
  int [] fPixels;

  MemoryImageSource fSource;
  int fFrame=0;

  /**
    * Do the image building in this method rather
    * than in a constructor so that it will know
    * the size of the panel after it has been added
    * to the applet.
   **/
  void init () {
    fWidth = getSize ().width;
    fHeight = getSize ().height;
    // Create an array to hold the color of each pixel
    fPixels = new int [fWidth * fHeight];
    // The MemoryImageSource creates an image from the array.
    fSource = new MemoryImageSource (fWidth, fHeight,
                                     fPixels, 0, fWidth);

    // Set the flag for animations.
    fSource.setAnimated (true);
    fImage = createImage (fSource);
  } // init

  /** Modify the pixel color parameters for each frame. **/
  void newFrame () {
    int index = 0;
    // Create a mask from the current frame number
    byte mask =  (byte) (fFrame & 0xff);
    int alpha = 255;


    for (int y = 0; y < fHeight; y++) {
       for  (int x = 0; x < fWidth; x++) {
          // Modify the color components each frame.

          int red =  (y * 255) / (fWidth - 1);
          red = red & mask;

          int green =  (x * 255) / (fHeight - 1);
          green = green & mask;

          int blue = 255 -  (255 * ( x - fWidth))/fWidth;
          blue = blue & mask;

          fPixels[index++] =
             (alpha << 24) | (red << 16) | (green << 8) | blue;
        }

    }
    fFrame++;
    // Push out the new data for a new frame.
    fSource.newPixels (0, 0, fWidth, fHeight);
  } // newFrame

  /** Draw the image on the panel. **/
  public void paintComponent (Graphics g) {
    g.drawImage ( fImage, 0, 0, this );
  }

}// class DrawingPanel

 

 

Obtaining a Pixel Array from an Image

We can obtain pixels from an existing image as follows. First create an array large enough to hold the pixels

int [] pixels = new int[width * height];

for an image of dimensions width x height. Then create an instance of the PixelGrabber class from the constructor

PixelGrabber pGrab = new PixelGrabber(image, x, y,
                                      width,height,
                                      pixels,
                                      offset, scansize);

where x,y give the coordinates of the upper left corner of the rectangle area within the image where the pixels are to obtained. The width,height arguments give the dimensions of the rectangle. The offset gives the starting point in the pixels array where to start putting the data and scansize is defined as the distance from one row of pixels to the next in the array.

Invoking the grabPixels() method:

  pGrab.grabPixels();

will result in the filling of the pixels array.

Note that this method can return before the pixel array has finished filling. The status of the pixel grabbing can be obtained with

 if((pg.getStatus() & ImageObserver.ALLBITS) != 0)) gotPixels = true;

Once we have the pixels we can do various manipulations on the pixels such as color filtering, edge finding, etc.

See the example program TransparencyApplet and the OutputPanel class in the transparency discussion for a demonstration of PixelGrabber.

References & Web Resources

 

Last update: May.24, 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.