📄 ch7.htm
字号:
<BLOCKQUOTE><TT>Image newImage = getImage(getCodeBase(),"image.gif");</TT></BLOCKQUOTE><P>The call you use depends on whether your image is grouped withthe class files or the HTML Web pages on your server.<BR><P><CENTER><TABLE BORDERCOLOR=#000000 BORDER=1 WIDTH=80%><TR VALIGN=TOP><TD><B>Note</B></TD></TR><TR VALIGN=TOP><TD><BLOCKQUOTE>You must be aware of the organization of your various data files on the server. If your images reside with your class files (/htdocs/classes/images), then use <TT>getCodeBase()</TT>; however, if your images reside with your html files (/htdocs/images), use <TT>getDocumentBase()</TT>. Many times, class files are grouped together with html files. In this case, both methods will return the same URL.</BLOCKQUOTE></TD></TR></TABLE></CENTER><P><P>The Toolkit also provides two <TT>getImage()</TT>methods:<UL><LI><TT>public Image getImage(URL imgLocation);</TT><LI><TT>public Image getImage(String filename);</TT></UL><P>Although the Toolkit can retrieve a filename, applets can't use<TT>getImage()</TT> to read localfiles because they would cause a security exception. Remember,applets can read only from the server they originated on. Allowingapplets to read from a local drive is definitely a security no-no.<H3><A NAME="ImageDisplay">Image Display</A></H3><P>Once an Image object is instantiated, it can be displayed in anapplet's <TT>paint()</TT> method byusing the Graphics object passed to it:<BLOCKQUOTE><TT>g.drawImage(newImage, x, y, this);</TT></BLOCKQUOTE><P>Variables <TT>x</TT> and <TT>y</TT>contain the coordinates of the image's upper-left corner, andthe final parameter is an ImageObserver object. This interfaceis implemented in the Component class that the applet is derivedfrom, which is why you can pass the <TT>this</TT>pointer. You'll learn more about the ImageObserver interface inthe next section.<P>There are four variations of <TT>drawImage()</TT>in the Graphics class:<UL><LI><TT>public abstract boolean drawImage(Imageimg, int x, int y, ImageObserver observer);</TT><LI><TT>public abstract boolean drawImage(Imageimg, int x, int y, int width, int height, ImageObserver observer);</TT><LI><TT>public abstract boolean drawImage(Imageimg, int x, int y, Color bgcolor, ImageObserver observer);</TT><LI><TT>public abstract boolean drawImage(Imageimg, int x, int y, int width, int height, Color bgcolor, ImageObserverobserver);</TT></UL><P>The width and height parameters allow you to scale an image, whichcan be enlarged or reduced in either the x or y direction. The<TT>bgcolor</TT> parameter specifieswhich color to use for any transparent pixels in the image. Each<TT>drawImage()</TT> version returns<TT>true</TT> if the image was painted,<TT>false</TT> otherwise. The imagewill not paint if it hasn't been loaded yet. It will eventuallydisplay because the Component class will be notified of the loadand will call your paint method when the image arrives.<H3><A NAME="ImageObservers">Image Observers</A></H3><P>The Component class accomplishes this because it implements theImageObserver interface. Most of Java's image-manipulation routinesare <I>asynchronous</I>, meaning they return immediately and notifyyou when they have completed their assignment. The notification,which flows through the ImageObserver interface, contains thefollowing method:<UL><LI><TT>public abstract boolean imageUpdate(Imageimg, int infoflags, int x, int y, int width, int height);</TT></UL><P>The Component class uses this method, but you can override itto get information about your image. The <TT>infoflags</TT>parameter is a bit flag; the settings for the bits are shown inTable 7.1.<BR><P><CENTER><B>Table 7.1. <FONT SIZE=1>Infoflags</FONT> bit valuesfor the ImageObserver interface.</B></CENTER><P><CENTER><TABLE BORDERCOLOR=#000000 BORDER=1 WIDTH=80%><TR VALIGN=TOP><TD WIDTH=124><I>Name</I></TD><TD WIDTH=466><I>Meaning</I></TD></TR><TR VALIGN=TOP><TD WIDTH=124><TT>WIDTH=1</TT></TD><TD WIDTH=466>Width is available and can be read from the width parameter.</TD></TR><TR VALIGN=TOP><TD WIDTH=124><TT>HEIGHT=2</TT></TD><TD WIDTH=466>Height is available and can be read from the height parameter.</TD></TR><TR VALIGN=TOP><TD WIDTH=124><TT>PROPERTIES=4</TT></TD><TD WIDTH=466>Image properties are now available. The <TT>getProperty()</TT> method can be used.</TD></TR><TR VALIGN=TOP><TD WIDTH=124><TT>SOMEBITS=8</TT></TD><TD WIDTH=466>Additional pixels for drawing a scaled image are available. The bounding box of the pixels can be read from the x, y, width, and height parameters.</TD></TR><TR VALIGN=TOP><TD WIDTH=124><TT>FRAMEBITS=16</TT></TD><TD WIDTH=466>A complete image frame has been built and can now be displayed.</TD></TR><TR VALIGN=TOP><TD WIDTH=124><TT>ALLBITS=32</TT></TD><TD WIDTH=466>A complete static image has been built and can now be displayed.</TD></TR><TR VALIGN=TOP><TD WIDTH=124><TT>ERROR=64</TT></TD><TD WIDTH=466>An error occurred. No further information will be available, and drawing will fail.</TD></TR><TR VALIGN=TOP><TD WIDTH=124><TT>ABORT=128</TT></TD><TD WIDTH=466>Image processing has been aborted. Set at the same time as ERROR. If ERROR is not also set, then you may try to paint the object again.</TD></TR></TABLE></CENTER><P><P>The following routine is used to repaint the applet when a completeimage arrives:<BLOCKQUOTE><TT>public boolean imageUpdate(Image whichOne,int flags, int x, int y, int w, int h)<BR>{<BR> if ( (flags & (ERROR | FRAMEBITS |ALLBITS)) != 0 )<BR> {<BR> repaint();<BR> return false;<BR> }<BR> return true;<BR>}</TT></BLOCKQUOTE><P>The return value specifies whether you would like to continueto get information on this image; returning <TT>false</TT>will stop future notifications.<H2><A NAME="TrackingImageLoading"><FONT SIZE=5 COLOR=#FF0000>TrackingImage Loading</FONT></A></H2><P>Image loading can also be tracked by using the MediaTracker class.Unlike the ImageObserver interface, it will not call back whensomething completes. The client of a MediaTracker object mustregister images with the tracker, then ask for status. <I>Registration</I>involves passing an image and assigning a tracking number to it,which then is used to query for the image's status. The followingmethods are available for image registration:<UL><LI><TT>public void addImage(Image image,int id);</TT><LI><TT>public void addImage(Image image,int id, int w, int h);</TT></UL><P>If a width and height are specified, the image will be scaledto these values. You can assign the same ID to multiple images.All the status-check routines can work on several images at once.<BR><P><CENTER><TABLE BORDERCOLOR=#000000 BORDER=1 WIDTH=80%><TR VALIGN=TOP><TD><B>Note</B></TD></TR><TR VALIGN=TOP><TD><BLOCKQUOTE>If you assign the same ID to two or more images, then you can't check on the individual status of each image. Only group status as a whole can be checked.</BLOCKQUOTE></TD></TR></TABLE></CENTER><P><P>You can use the following routines to get status information:<UL><LI><TT>public boolean checkAll();</TT><LI><TT>public boolean checkAll(boolean load);</TT><LI><TT>public void waitForAll();</TT><LI><TT>public boolean waitForAll(long timeout);</TT><LI><TT>public int statusAll(boolean load);</TT><LI><TT>public boolean checkID(int id);</TT><LI><TT>public boolean checkID(int id, booleanload);</TT><LI><TT>public void waitForID(int id);</TT><LI><TT>public boolean waitForID(int id,long timeout);</TT><LI><TT>public int statusID(int id, booleanload);</TT></UL><P>The MediaTracker class can be passed a load parameter. If thisparameter is <TT>true</TT>, then theimage (or images) will start to load. Remember, <TT>getImage()</TT>does not actually load the image. MediaTracker can be used topreload an image before it is displayed. The methods returninga Boolean value will indicate <TT>false</TT>unless all eligible images are complete. Images that encounteran error are considered to be complete, so you have to check forerrors with these routines:<UL><LI><TT>public boolean isErrorAny();</TT><LI><TT>public Object[] getErrorsAny();</TT><LI><TT>public boolean isErrorID(int id);</TT><LI><TT>public Object[] getErrorsID(int id);</TT></UL><P>The integer returned by <TT>statusAll()</TT>and <TT>statusID()</TT> uses a bitflag much like <TT>imageUpdate()</TT>does; the values for the bit flag are listed in Table 7.2. Thewait methods will block until all images are complete. You canalso specify a time-out in milliseconds that determines the maximumtime to wait.<BR><P><CENTER><B><FONT SIZE=2>Table 7.2. Status bit values for MediaTracker.</FONT></B></CENTER><P><CENTER><TABLE BORDERCOLOR=#000000 BORDER=1 WIDTH=80%><TR VALIGN=TOP><TD WIDTH=112><I>Name</I></TD><TD WIDTH=293><I>Meaning</I></TD></TR><TR VALIGN=TOP><TD WIDTH=112><TT>LOADING=1</TT></TD><TD WIDTH=293>Some (or all) images are still loading.</TD></TR><TR VALIGN=TOP><TD WIDTH=112><TT>ABORTED=2</TT></TD><TD WIDTH=293>Some (or all) images have aborted.</TD></TR><TR VALIGN=TOP><TD WIDTH=112><TT>ERRORED=4</TT></TD><TD WIDTH=293>Some (or all) images have encountered an error.</TD></TR><TR VALIGN=TOP><TD WIDTH=112><TT>COMPLETE=8</TT></TD><TD WIDTH=293>Some (or all) images have loaded.</TD></TR></TABLE></CENTER><H2><A NAME="TheConsumerProducerModel"><FONT SIZE=5 COLOR=#FF0000>TheConsumer/Producer Model</FONT></A></H2><P>In Java, the Image class is just the tip of the iceberg; beneathit stand the ImageConsumer and ImageProducer interfaces. Imagedata is originated in an object that adheres to the ImageProducerinterface, which sends the data to an object using the ImageConsumerinterface. Figure 7.1 illustrates this relationship.<P><A HREF="f7-1.gif" ><B>Figure 7.1 : </B><I>The relationship between ImageProducer and ImageConsumer </I></A><P>This model allows any type of object to both originate and receiveimage data. By creating the image subsystems as interfaces, Sunhas freed image production from any specific object type. Thisis an important abstraction that you'll exploit in this chapter'sproject.<H2><A NAME="JavaColorModels"><FONT SIZE=5 COLOR=#FF0000>JavaColor Models</FONT></A></H2><P>As stated earlier, an image is a collection of colors and theirlayout. Much research has been done on how color is represented.Humans perceive color when combinations of wavelengths of visiblelight stimulate the retina. The number of wavelength combinationsis infinite, but humans can see only a fixed subset as separatecolors. Therefore, <I>color models</I> were invented to grouphuman-visible colors into a working set. There are two predominantcolor models used to represent color information:<UL><LI>The CMY (cyan-magenta-yellow) color model is used in subtractivecolor systems, such as printing.<LI>The RGB (red-green-blue) color model is used in additive colorsystems, such as television and computer screens.</UL><P>Printing is a <I>subtractive system</I> because the perceivedcolor is contained in wavelengths of light reflected from thepaper. The absorbed colors are said to be "subtracted"from the perceived color. Conversely, an <I>additive color system</I>creates the light source containing the color. Therefore, youcan watch television in the dark, but you can't read a magazine.<BR><P><CENTER><TABLE BORDERCOLOR=#000000 BORDER=1 WIDTH=80%><TR VALIGN=TOP><TD><B>Note</B></TD></TR><TR VALIGN=TOP><TD><BLOCKQUOTE>If you're really curious, cyan absorbs red light, magenta absorbs green light, and yellow absorbs blue light. CMY color systems subtract RGB light and thus control the appearance of RGB color on a printed page.</BLOCKQUOTE></TD></TR></TABLE></CENTER><P><P>Java encapsulates color information for an image in the ColorModelclass. Using the model, pixel data is interpreted into a raw colorcomponent (red, green, blue, and alpha) for display. The ColorModelclass has the following methods:<UL><LI><TT>public static ColorModel getRGBdefault();</TT><LI><TT>public int getPixelSize();</TT><LI><TT>public int getRed(int pixel);</TT><LI><TT>public int getGreen(int pixel);</TT><LI><TT>public int getBlue(int pixel);</TT><LI><TT>public int getAlpha(int pixel);</TT><LI><TT>public int getRGB(int pixel);</TT></UL><P>The lone static method returns the system default ColorModel.<H3><A NAME="DefaultRGB">Default RGB</A></H3><P>Java uses the RGB color model for all its painting; all othermodels are eventually translated into this format. It has 8 bitsof red, 8 bits of green, 8 bits of blue, and 8 bits of alpha.The alpha channel supplies transparency-255 is opaque (visible),and 0 is transparent. These add up to 32 bits of color information,which just happens to be the size of a Java integer. The formatof colors within an integer is <TT>0xAARRGGBB</TT>.<P>To support images, Java supplies two other ColorModels: DirectColorModeland IndexColorModel.<H3><A NAME="DirectColor">Direct Color</A></H3><P>The DirectColorModel is used when the underlying pixels in an
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -