You are on page 1of 6

Chapter 6

Images
• what an image really is
• image observers
• Java’s memory image source class
• colour models and images
• image producers, consumers and filters
• Java.AWT.image buffered image class
Image have a big job to do. It takes a lot to make an image especially if the source is
some find out on the network. The bits that represent the image must be loaded from the
network and stored locally. From the user's perspective, all of the processing should have
minimal impact on their computers performance. From the programmers perspective, the
process of moving pixel information from the network to the windowing system should
be encapsulated in the various support classes, so that to the greatest extent possible, the
whole arrangement is hidden.
In practice, the whole arrangement is indeed hidden, but it's like a slightly fat beer hiding
behind a slightly thin tree there are places where bits of the beer stick out into view,
alarmingly casual passerby. Many image related methods require a mysterious extra
parameter of type image observer. The get image() require a mysterious extra parameter
of type image observer. We get image() method seems to return immediately, even when
loading a large image from a slow network. Sometimes you can create an off screen
image and sometimes you cannot.

There are two important things to learn from this chapter if a similar way that the image
infrastructure works. Equally important is an understanding of which parts of that
infrastructure can be usefully modified and which are best left alone
The Image Infrastructure
the image a class is abstract or stop you never construct one (that would be impossible
because the class is abstract). Instead you have two options. You can call the create
image() method or you can create an instance of the Java.AWT.image. Buffered image
class.

Most of this chapter concern images that are created with the create image(). The
buffered image class was introduced as part of the JDK release 1.2. This class is easy to
use but it does not offer the functionality that is available when you call create image().
The buffered image class is discussed at the end of this chapter.
Image creation and retrieval the create image() method is a part of the component class.
Usually the component’s create image() method just tells its peer to create image(). The
peer is the lead from specific bundle of calls to native methods. Thus the object returned
by
Create image () is a platform specific subclass of image. Not surprising really it's
methods are primarily caused native methods.

For example consider what happens in a create image() call the init() of an applet running
on Solaris/Motif platform. The applet peer is a subclass of I component peer in the
sun.awt.Motif package. The componentPeer class has its own create image() method that
constructs and returns an instance of X11 image, which is a concrete subclass of the
abstract image class. After this is much implicate processing, the ex-woman image
construct the causes native calls into the Solaris/Motif version of the Java library; a pixel
map is created in the X server, and the ex-woman image communicate with these map.

Note: the handling of the image class is a perfect example of polymorphism as


programmers we believe that we are using an instance of class image in fact we are using
whatever subclass of image is appropriate to our platform, the chore of deciding which
subclass to be used is taken care of for us. The entire mechanism is so well encapsulated
that we never need even to know about it. Many successful Java program have been
written by people who were not aware of the image is abstract

Using create image() you can create a fresh image. You can also load an image from a
remote file, where the get image() method of the component class. Here, Java Moose to
great lengths to optimise performance. The simplest strategy would be for get image() to
make a connection to the machine that owns the remote graphics file, load the file, pass
it, and can start and return an image. The strategy would be adequate in a perfect world,
but in the real world, it could likely introduce extreme delays for two reasons:
• the connection is to be more machine might be slow. Play the applet would be a
site is idling while waiting for network response.
• The user might never bring the applet into a state where the image was needed.
The time spent in loading the image would have been wasted
• to avoid these problems, Java and forces the following policy with respect to
remote image files
• Bullet all remote images are loaded by asynchronous threads.
• These that do not begin to load until the corresponding image is used, or observed
The mechanism that enforce these policies are almost completely hidden from
programmers. Programmatically, the biggest clue that something is going on its that
certain method requires an extra parameter of type image of the world brought
behaviourally, the biggest clue that Java is doing something complicated is when an
applet crashes the first time it paints a large image.

This were unfamiliar with image flashing are invited to run the flasher applet. The first
time the program runs in any browser session, the image does not match between chunks.
The text field at the top of the applet indicates that the applet is receiving an
extraordinary number of repaint() calls. The code for the applet is quite simple and
appears below and on the CD-ROM injavadevhdbk\ch06\flasher.java the byte code is on
the CD-ROM in javadevhdbk\ch06\flasher.class. At the end of the listing is a method
that would eliminate the flashing effect was not commented out. The reason for the
flashing and graphics are explained in the next section.
Flasher.java

import java.awt.* ;
import java.awt.image.* ;
import java.applet.Applet ;
public class Flasher extends Applet
{

Image im ;
TextField tf;
int nRepaints ;
int nPaints ;

public void init ( )


{

setLayout(new BorderLayout());
tf = new TextField();

add(tf, BorderLayour.NORTH);

// Load image from server of applet.


Im = getImage(getDocumentBase() , “Hammock.jpg”) ;
}

// This is the version of repaint( ) called by imageUpdate().


public void repaint(long tm, int x int y , int w, int h)
{
nRepaints++,
super.repaint(tm,x, y, w, h);
}
public void paint(Graphics g)
{
nPaints++;
tf.setText(nRepaints+ “repaints, “ + nPaints + “ paints, “ +
“width = “ + im.getWidth(this) +
“ , height = “ + im.getHeight(this));

Image observers
the image observer mechanism is in a sample of the observer design pattern. The idea is
to permit an object to be”observed”by an arbitrary number of other objects when the
object being observed experience a change that the observer should know about the
observed object makes a method call to all the observers the object being observed as the
discretion to decide when the observers should be notified

Note: for programmers who wish to apply the Observer/observed paradigm to their own
designs, Java offers the interfaces observer and observed able in the Util package. Image
do not actually use these interfaces.
In Java’s paradigm, the colour value for image are delivered by an object that implements
the image producer interface, which is covered in detail later in this. A remote image, the
image producer is a thread that communicates via TCP/IP with the server that contains
the image file.
Recall Java’s policy that the producer thread will asynchronously (in the background).not
beginning its until the image is observed. For this reason, the getimage() returns
immediately. The value returned is a reference to an instance of image with weight and
height both set to-1. Eventually, the width and height will be set to the correct values.

Several methods can make the system decided the image has been observed. The most
common is graphic.DrawImage(), which renders the image onto the screen. This method
requires an extra parameter of the image observer, which is the interface, not a class or
stop the component class implements the interface. The easiest way to call graphics draw
image() is to pass as the image observer a reference to the component in which the image
is being branded.
The call to draw image() causes the image producer to start producing periodically, the
producer delivered new information to the image and then makes a call to the image
update() method of the images observer. The meaning of the call is,”the image has
changed, and here's how , and you might want to do something about it.”The API for
image update() is:
Public Boolean imageUpdate(Image im,int flags,int x,int y ,int width,int height)
the Flex parameter describes the new information being reported by the current image
update() call the X, Y, width and height parameters specify the bounding box of the
image data delivered so for. However, the four bounding box parameter cannot be
depended on to be valid unless they are referred to by one of the flags. The flags values
are described in table 6.1.

Table 6.1
Value Meaning
image observer.Width -the images with has been updated and may be lead from the width
parameter from the images get width() method.
Image observer.height -the images height has been updated and maybe read from the high
parameter from the images get hight() method
ImageObserver. Properties - the image’s properties have been updated and maybe read
from the images get properties() method.
Imageobserver.SomeBITS -more pixels have been delivered for an image.
Imageobserver.FRAMEBITS -a complete claim for multiple frame image has been
delivered
Imageobserver.ALLBITS -the images is complete
Imageobserver.ERROR-an error has occurred in production
Imageobserver.ABORT production has been abnormally terminated

For example, the width parameter should not be used unless the bit rate of the flag
value is set. Even when set, the values of it is just the current width. In most cases,
that width at the become a reality with attains its ultimate value early in the process,
but this cannot be guaranteed to stop generally,height does not get set to its ultimate
value until production is all but finished.
The image update() method of component just calls repaint() so that the more
complete image is rendered. This could easily result in several hundred calls to the
repaint() just request a call to update() in the near future. Most of the calls occur after
some other call has already made the request but before the update thread has run, so
nothing happens. The hundred calls to repaint() result in only a few calls to update()
and paint(). those few calls, however, will produce a visible fleshing of the image as
update() clears the screen and paint() draws the incomplete image. You saw how the
flashing Occurs in the flasher applets presented in the previous section. Flasher
demonstrates the flashing phenomenal, the number of calls to paint() and repaint()
and the image’s size.
One way to eliminate the flashing is to override image update() so that it only repaints
when the complete image is available. The code below does the trick (this is the code
that is commented out in Flasher)
public boolean image update (image img,int flags, int x,int y ,int width,int height)
{
if ((flags & image observer .ALLBITS)!=0)

Repaint ();
Return true;
}
they fix certainly works, but if there are multiple images, the code gets a bit more
complicated(it would be desirable to be paid only once, when all the images are
complete). Moreover, if this is happening in an applet are free of any complexity, layout
consideration may call for subdivision into panels. In this case, some of the logic from
imageUpdate() must be moved into the sub panels own image update() method.
Overriding image update() is generally not the best strategy for waiting for an image. A
much better be to use the Java.AWT.media Tracker class, which is the subject of the next
section.
The media Tracker
it offen happens that an applet or application cannot do anything useful until certain
images are fully loaded. A prime example is an applet that just presents an animation.
The animation is bigger before all the frames are available, somewhere there will be a
delay of blank frame. As things stand the situation is deadlocked. The image is not to be
displayed until it is loaded, but the system will not even start to load the image until it
tries to display the image.

The media Tracker class solves the problem by providing a sly , unseen observer for each
image so the pixel loading thread can be kicked off on demand. This mechanism is
hidden from the programmer, who simply register images with the tracker.
The constructor for media Tracker is:
media Tracker(component target)
the target parameter can be any component, but for ease of reading, it should be
something simple, such as the applet.

After an image is created via getimage(), it can be registered with the tracker with the egg
image() method:
Tracker.addImage(image,n)
yeah, image is the image to be tracked. The second parameter is an ID or category.
Tracker can be asked to load all of its images or just those with a certain ID. the methods
are described below:
void waitforAll() throws interrupted exception days until all registered images are loaded

You might also like