Image抽象类,定义的方法提供对图像信息的访问。而创建和处理图像的基本机构则在image包里。
Image方法:
void flush() //刷新此Image对象使用的所有可重构资源。
float getAccelerationPriority() //返回加速优先级提示的当前值。
ImageCapabilities getCapabilities(GraphicsConfiguration gc) //返回一个ImageCapabilities对象,可以在指定的GraphicsConfiguration上查询此Image的功能。
abstract Graphics getGraphics() //创建用于绘制到屏幕外图像的图形上下文。
abstract int getHeight(ImageObserver observer) //确定图像的高度。
abstract Object getProperty(String name, ImageObserver observer) //按名称获取此图像的属性。
Image getScaledInstance(int width, int height, int hints) //创建此图像的缩放版本。
abstract ImageProducer getSource() //获取生成图像像素的对象。
abstract int getWidth(ImageObserver observer) //确定图像的宽度。
void setAccelerationPriority(float priority) //为此图像设置有关加速度有多重要的提示。
getWidth与getHeight返回的高度和宽度都是在图像完全被加载后才有效的
getSourse的意义是为了过滤该图像
图像都有一个与之关联的Graphics,对图像进行画面外缓冲
Graphics提供的重载的drawImage方法,可以将缩放后的图像画出来
flush刷新图像使用的所有资源,包括高速缓存的图像像素和系统资源,图像被完全重构的时,刷新图像是一个必须的过程
AWT中,许多图像操作都是异步进行的。例如,如果在调用的同时没有加载图像,drawImage ()什么也画不出来,而只是产生与图像相关的位。
g.drawlmage ( image,o,o,this) ;
图像相关联的位不在java.awt.Image中,但每个图像都维护一个和ImageProducer的关联。
她的作用是生产图像的位并将他们传递给ImageConsumer。
图像生产者生产位。
该接口中定义了一个常数集合和一个方法。
方法:
public voolean imageUpdate(Image img,int flags, int x, int y, int width, int height);
flags的作用是通知图像观察者图像象生产的进展。下面的表中的常数代表传递给imageUpdate的flags参数中的位
标志 | 含义 |
---|---|
ABORT | 图像加载被中断 |
ALLBITS | 所有的位都已经加载给图像 |
ERROR | 在加载过程中发生错误 |
FRAMEBITS | 多帧图像的一个帧传送,一般用于动画GIF |
HEIGHT | 图像的高度已经可用 |
PROPERTIES | 图像的属性已经可用 |
SOMEBITS | 图像的缩放变倜的多个位已可用 |
WIDTH | 图像的宽度已经可用 |
ImageObserver 的实现普遍存在于AWT中,这是因为java.awt.Component 实现 ImageObserver。所以,每个构件都是ImageObserver,当一个给定的 ImageProducer 采取异步操作时,这个Ima-geObserver可以选择是否被更新。
ps:所有的构件都是图像观察者,所以任何构件都可以被传递到要获取ImageObserver参数的方法中。
import java.applet.Applet;
import java.awt.*;
import java.net.URL;
public class demo06 extends Applet {
Image image;
@Override
public void init() {
URL codeBase = getCodeBase();//这个applet位置的URL
System.out.println(codeBase);
image = getImage(codeBase,"1.jpg");//返回对图像的引用,为了阐明加载图像的异步行为,图像的宽度和高度在getImage()返回后立即被显示出来
System.Out.print(image.getWidth(this));
System.Out.print(image.getHeight(this));
}
public void paint(Graphics g){
g.drawImage(image,0,0,this);
}
}
显示图像的宽度和高度都只是临时值,尽管这时getImage已经返回对图像的引用,但定义图像的位还没有被加载。Image相关的图像位在需要之前不被生产。所以在图像完全加载前,getWidth和getHeight都是-1。
下面解释上面程序现象的原因:
上面所讲的方法一直被循环调用,直到图像被完全加载:图像生产者加载图像的部分并调用图像观察者中的imageUpdate ()。当图像观察者是AWT构件时,Component . imageUpdate ()调用repaint ()方法清除构件背景并调用paint ()。在上面列举出的程序范例中,applet 的 paint()调用drawImage ()方法绘制出刚刚得到的图像位。重复循环,图像生产者加载图像的下—块,调用图像观察者的imageUpdate ()。当图像被完全加载时,图像生产者停止调用观察者imageUpdate (),循环中断。
public void paint(Graphics g){
g.drawImage(image,0,0,this);
System.out.println(image.getWidth(this) + "后"); //加载完图像后,正确打印宽度
}
applet 获取图像提供内部支持,也就是Applet. getImage方法。而对于Java应用程序来讲,没有扩展applet,所以应用程序实现合并图像时,不同于 applet。
在ImageTestApplication构造器中,应用程序获取图像的引用。应用程序从Toolkit类中调用getImage ()方法,而不是调用Applet . getImage ()方法。
首先,调用Toolkit类中的static getDefaultToolkit()方法,为返回应用程序运行的平台默认的工具包。然后,调用工具包中的getImage方法,该方法返回java.awt. Image的引用。在这里要注意的是 Toolkit.getImage()被重载,来获取URL或String参数。
applet和应用程序之间的另一个区别是:应用程序的显示位置必须被考虑。如果图像已经在(0,0)处被画出,就像在程序范例5-1所给出的applet 代码一样,图像的顶部将被绘制在框架标题条的下面。applet 的左上角位于applet菜单条的下面,而应用程序的左上角则是位于其框架的顶端。
注意,addNotify ()被覆盖以得到框架的空白区的引用,其目的是为了设置框架的边框。在框架的同位体被创建之前,getInsets ()一直返回值为(0,0,0,0)的空白区。同位体由addNotify ()创建,所以调用getInsets ()方法必须在其框架对应的同位体被创建之后。请参见11.8节“构件和同位体”中的相关内容,可以得到更多的关于同位体和覆盖addNotify ()的信息。
最后,图像的尺寸大小是硬编码进应用程序的,这种方法明确地不被推荐实行:
setBounds(100,100,217 + insets.left, 321 + insets.top);
所有的applet程序和应用程序实现加载和显示图像都是采用从图像的顶部到底部的方式进行的,这是由于图像加载的异步所导致的。一个比较美观、令人满意的方法是在图像显示之前等待图像完全加载。有很多的途径可以用来实现该效果,其中的一个途径就是使用imageUpdate()方法,使用该方法可以获得加载图像的进展状况。
重写imageUpdate()方法,在imageUpdate()中调用repaint()方法
@Override
public boolean imageUpdate(Image img, int infoflags, int x, int y, int w, int h) {
System.out.println(h);
repaint();
if((infoflags & ALLBITS) == 0) {
return true;
}else {
return false;
}
}
但这样会引起闪动,消除闪动:重写update方法。因为调用repaint(),update()会被触发调用,但在缺省模式下update会先清除构件中所有的背景,在调用构件中的paint方法。
public void update(Graphics g){
paint(g);
}
与图像的异步加载相比,这个类提供了一个比较方便的方法,可以跟踪图像的加载。
使用MediaTracker分为下面的三步:
1)创建MediaTracker实例。
2)使用 MediaTracker . addImage ()指明要跟踪的图像对象。
3)创建try/catch 块。try 块等待和ID相关的图像完全加载。
由于MediaTracker 的 waitForID方法可能抛出InterruptedException,所以实现catch块是必要的。
如果你希望在显示图像之前,先将图像完全加载,可以使用MediaTracker。使用MediaTracker意味着你不必覆盖imageUpdate ()方法,而且不必通过将变量flags和正确的常量求与来判断什么时候图像被完全加载。
public static void waitForImage(Component component, Image image){
MediaTrachker tracker = new Mediatracker(component);
tracker.addImage(image,0);
tracker.waitForID(0);
}