Dr. Dobb's is part of the Informa Tech Division of Informa PLC

This site is operated by a business or businesses owned by Informa PLC and all copyright resides with them. Informa PLC's registered office is 5 Howick Place, London SW1P 1WG. Registered in England and Wales. Number 8860726.


Channels ▼
RSS

JVM Languages

Java Q&A


MAY96: JAVA Q&A

Cliff is vice president of technology and Steve president of Digital Focus. They can be contacted at [email protected] and [email protected], respectively.


This is the first installment of a new column designed to answer your questions about Java. Each month we will select questions submitted to The Java Developer Web site (http:// www.digitalfocus.com/faq/), an independent forum for the exchange of technical information about Java. We also are constructing a Java lab that will focus on the use of Java technology within intranets, the Internet, and embedded environments. This will provide a base from which to evaluate technology and explore new ways to use Java to solve real-world problems. We welcome you to this column and hope to answer the questions that are of most interest to you. If you have specific questions or contributions, please submit them via our Web site.

--C.B. & S. A.

Graphic image display in Java involves issues such as the types of supported image file formats, image source (local, remote, or program generated), and monitoring of the loading process.

Currently, Sun's Java graphics programming library (AWT) supports GIF and JPEG images. Format considerations include local color palettes, feature restrictions (compression, color depth, and interlacing, for example), and dithering.

This month, we'll examine the techniques necessary to load an image from a local file, remote location, and memory. In the coming months, we'll discuss issues such as monitoring the loading process.

Loading an Image from a Local File

To load a single image in an application (a Java program run from the command line), use Image img = myWindow.getToolkit() .getImage("orion.jpg"); to load the JPEG image file orion.jpg (where myWindow is the Window or Frame object in which you want to display the image).

In a browser applet, use Image img = ((Window)(myApplet.getParent())) .getToolkit().getImage("orion.jpg");, where myApplet is the applet in which you plan to display the image. Note that this assumes the applet is instantiated inside a Frame or Window, which is consistent with the way Netscape handles applets.

After the Image is loaded, display the image by drawing it in a Graphics context. (Every AWT component object has a Graphics context.) This is done in the paint() method of a component, because paint() is called by AWT automatically when the image is done loading; see Listing One. Image loading is asynchronous. Loading does not necessarily occur until you attempt to display the image, via drawImage(). The last parameter to drawImage() specifies which component to repaint when the image is finally ready. This is normally the component that calls drawImage() in the first place. The following sequence of events occurs:

    1. When the applet is first loaded, paint() is called for each component; in Listing One, the component calls drawImage().

    2. The applet continues processing without waiting for the image. (The applet does not even know how big the image is.)

    3. AWT finishes fetching the image, if it has not already.

    4. When the image is ready to display, AWT calls imageUpdate() for the component you specified in drawImage(). This is effectively a callback, although we have achieved it in an object-oriented way--by passing an object instead of a function.

The default behavior of imageUpdate() is to repaint the component by calling its paint() method again. Since the image is now available, it will be redrawn. Its dimensions are now known as well.

Since image loading is asynchronous, you cannot call loadImage() followed immediately by drawImage() and expect to see the image--drawImage() will start fetching the image, but it cannot display it until the image is available. You must take advantage of the callback mechanism that calls paint() to ensure that a final call to drawImage() is made when the image has been loaded.

Loading a Remote Image

Images loaded across a network have the same considerations, except you must use a version of getImage() that takes a URL object as a parameter. Construct the URL object in the getImage() call like this: applet .getImage(new URL("www.somewhere .com/orion.jpg"));.

Here, we have used an applet getImage() member function rather than the Toolkit member function used earlier. Since the applet getImage() method uses a URL argument (rather than a filename), it is appropriate for retrieving a remote file. Specifying a file URL using the file:/// syntax apparently is not yet fully implemented.

Loading from MemoryImageSource

If an image can be algorithmically generated, it may be more efficient to create the image on-the-fly rather than load it from a persistent source such as a disk or server. There is no need, for example, to obtain a simple color gradient from a bitmap file.

Several objects and interfaces allow you to implement memory-based image objects in Java. The key class, MemoryImageSource, creates in memory an image object containing the color model, physical dimensions, offset, and (of course) actual pixel information. With this class, creating an image is a two-step process: First, define an int or byte array and populate it with data; see Listing Two. Next, use that array to create a memory object (MemoryImageSource) that serves as the source of data for the new image; see Listing Three.

MemoryImageSource has six constructors that give you a range of options in array types, color models, and properties. The createImage() method can take either a width and height parameter or an ImageProducer object such as MemoryImageSource. For any type of image processing using data arrays, use the MemoryImageSource implementation.

It is easy to introduce variations in image array processing. The result is a fast and efficient image-display technique for your Java applet or application. Listing Four presents a complete working demo.

Listing One

class MyCanvas extends Canvas
{
    Image image;
    public MyCanvas(Image img) { image = img; }
    public void paint(Graphics g)
    {
      // Draw the image on the Graphics context. This is non-blocking.
      g.drawImage(image, 0, 0, this);
    }
}

Listing Two

public Image makeImage(int width, int height)
{
    int index = 0;
    int myImageData[] = new int[ width * height ];
    for(int y = 0; y < height; y++)
    {
        int a = y * (255 / ((height/20)-1));
        for(int x = 0; x < width; x++)
        {
            int b = x * (255 / ((width/20)-1));
            myImageData[index++] = (255 << 24) | (a << 16) | b;
        }
    }

Listing Three

  myImage = createImage(new MemoryImageSource(width, height, 
                                                     myImageData, 0, width));
  return myImage;       
}

Listing Four

import java.awt.*;
import java.applet.*;
public class ImageDemoApplet extends Applet
{
    static Frame frame;
    MyCanvas canvas;
    Image image = null;
    public void init()
    {
        image = getParent().getToolkit().getImage("orion.jpg");
        canvas = new MyCanvas(image);
        add(canvas);
    }
    public static void main(String args[])
    {
        frame = new Frame();
        ImageDemoApplet app = new ImageDemoApplet();
        frame.add("Center", app);
        frame.resize(200, 200);
        app.init();
        app.start();
        frame.show();
    }
}
class MyCanvas extends Canvas
{
    Image image;
    public MyCanvas(Image img)
   {
        image = img;
        setBackground(Color.white);
        resize(100, 100);
    }
    public void paint(Graphics g)
    {
      // Draw the image on the Graphics context. This is non-blocking.
      g.drawImage(image, 0, 0, this);
    }
}


Related Reading


More Insights






Currently we allow the following HTML tags in comments:

Single tags

These tags can be used alone and don't need an ending tag.

<br> Defines a single line break

<hr> Defines a horizontal line

Matching tags

These require an ending tag - e.g. <i>italic text</i>

<a> Defines an anchor

<b> Defines bold text

<big> Defines big text

<blockquote> Defines a long quotation

<caption> Defines a table caption

<cite> Defines a citation

<code> Defines computer code text

<em> Defines emphasized text

<fieldset> Defines a border around elements in a form

<h1> This is heading 1

<h2> This is heading 2

<h3> This is heading 3

<h4> This is heading 4

<h5> This is heading 5

<h6> This is heading 6

<i> Defines italic text

<p> Defines a paragraph

<pre> Defines preformatted text

<q> Defines a short quotation

<samp> Defines sample computer code text

<small> Defines small text

<span> Defines a section in a document

<s> Defines strikethrough text

<strike> Defines strikethrough text

<strong> Defines strong text

<sub> Defines subscripted text

<sup> Defines superscripted text

<u> Defines underlined text

Dr. Dobb's encourages readers to engage in spirited, healthy debate, including taking us to task. However, Dr. Dobb's moderates all comments posted to our site, and reserves the right to modify or remove any content that it determines to be derogatory, offensive, inflammatory, vulgar, irrelevant/off-topic, racist or obvious marketing or spam. Dr. Dobb's further reserves the right to disable the profile of any commenter participating in said activities.

 
Disqus Tips To upload an avatar photo, first complete your Disqus profile. | View the list of supported HTML tags you can use to style comments. | Please read our commenting policy.