Java Tip 16: Creating in-memory images in Java

Save network bandwidth by creating images at run time

Have you ever wanted to work with really simple images that are easily created from memory (color gradients, stripes, fractals, and so on) but didn't know how to create one in Java? Did you then go ahead and create a GIF/JPEG file that had to be transported across the Internet for every user? With a little bit of work, you can create in-memory images within Java and not consume precious network resources.

To create an in-memory image, you need to create a one-dimensional array of pixel data. The two-dimensional pixel data are flattened into a one-dimensional array by placing the pixel at position (x, y) into the array at position (y*width+x). Each entry in the array represents a single pixel in the final image. Depending upon the color model used, that entry is either the combined RGB value of the pixel (plus alpha value for transparency) or an index into a color index array. Once you have your pixel array, you create the image by calling createImage. The single parameter to the method is a new instance of MemoryImageSource, with your pixel array and image size as its parameters.

The default ColorModel used by Java stores the blue value in bits 0-7, green in 8-15, red in 16-23, and the alpha value in 24-31. When alpha is zero, the pixel is transparent and the background color is seen through. When alpha is 255, the pixel is opaque and the actual pixel color is displayed. Values between 0 and 255 will let the background color bleed through.

The following applet creates a pixel array using a sine wave to set color values. (All the pixels are fully opaque.) Once you have the pixel array, you create the image with the i = createImage (new MemoryImageSource (width, height, pixels, 0, width)) call. As long as the pixel array is the entire image, the offset parameter for the MemoryImageSource constructor will be 0, and the scan size parameter will be the image width. You can then use the image like any other image retrieved across the network.

You need a Java-enabled browser to view this applet.

Here is the source code.

When using IndexColorModel, you need to provide multiple arrays: one for the pixel array and three for the color arrays -- one each for the red, green, and blue part of each color entry. The pixel array can be a byte array since each color array is restricted to 256 values.

The following applet creates the color arrays using different shades of green, and the pixel array is filled using modulo arithmetic. Once you have the color arrays and pixel array, you create the image with the i = createImage (new MemoryImageSource (width, height, new IndexColorModel (8, arraySize, reds, greens, blues), pixels, 0, width)) call. Everything else is just the same as with the default ColorModel.

You need a Java-enabled browser to view this applet.

Here is the source code.

That's all there is to it.

Although not a java drinker (he gets his caffeine fix from Coke), John Zukowski has been consulting for most of the past decade. After founding the Mid-Atlantic Java User Group (MAJUG), John relocated to Boston from Washington, D.C., to start on a new endeavor with Monash Information Services. He is the author of the upcoming book AWT Reference Manual from O'Reilly and Associates.