本站首页    管理页面    写新日志    退出


«August 2025»
12
3456789
10111213141516
17181920212223
24252627282930
31


公告
 本博客在此声明所有文章均为转摘,只做资料收集使用。

我的分类(专题)

日志更新

最新评论

留言板

链接

Blog信息
blog名称:
日志总数:1304
评论数量:2242
留言数量:5
访问次数:7599989
建立时间:2006年5月29日




[J2SE]AWT使用ImageProducer/ImagConsumer模式加载和显示图像的原理[转]
软件技术

lhwork 发表于 2006/10/23 10:17:23

AWT 使用 ImageProducer / ImagConsumer 模式,支持加载和显示 GIF 图像文件格式和 JPEG 图像文件格式。因为图像的加载和显示是异步方式进行的,所以有大量加载和显示的技术。在 AWT 中,提供了一个 java.awt.Image 类。java.awt.Image 类代表一个图像对象被作为参数传递给其他用来显示和处理图像的其他 AWT 对象使用。例如,通过调用 Graphics.drawImage(java.awt.Image, int, int, ImageObserver) 方法,可以在组件中画出图像。java.awt.Image 是一个定义方法的抽象类,它定义的方法提供的对图像信息的访问。而创建和处理图像的基本结构则在 java.awt.image 包中。注意,这里不要和 java.awt.Image 发生混淆。AWT  加载和显示图像使用的是 ImageProducer / ImagConsumer 模式,我们必须了解3个术语,ImageProducer(图像生产者),ImageConsumer(图像消费者)和ImageObserver(图像观察者)。ImageProducer 负责生产图像的位,ImagConsumer 接受图像的位,ImageObserver 监视 ImageProducer 的图像生产过程。ImageProducer 生产传递给 ImagConsumer 与图像相关的位。因为图像生产过程是异步进行的,并不是一次性生产所有图像位,所以当 ImageProducer 加载图像时,ImageObserver 用来监视它的进展情况。因为 java.awt.Component 实现了 ImageObserver 接口,所以 AWT 中的每个组件都可以是ImageObserver,当一个给定的 ImageProducer 进行异步操作时,这个 ImageObserver 可以选择是否被更新。java.awt.image 包为 ImageProducer,ImagConsumer 和 ImageObserver 都定义了接口。ImageProducer 和图像相关的位并不存储在 java.awt.Image 中,每个图像都维护一个和一个 ImageProducer 的关联。这个 ImageProducer 的责任是生产图像的位并将它们传送给 ImagConsumer,用于过滤该图像。java.awt.image软件包中,FilteredImageSource(被过滤的图像源)和 MemoryImageSource(内存的图像源)实现了 ImageProducer  接口,是 ImageProducer 。ImagConsumerjava.awt.image软件包中,ImageFilter(图像过滤器)和 PixelGrabber(像素抓取器)实现了 ImagConsumer 接口,是 ImagConsumer。ImageProducer 和 ImagConsumer 的详细介绍请阅读 使用 ImageProducer  / ImagConsumer 进行图像过滤ImageObserverImageObserver接口中,定义了一个常数集合和一个方法:public boolean imageUpdate(image img, int flags, int x, int y, int width, int height); ImageObserver的常数 标志 含义 ABORT 图像加载被中断 ALLBITS 所有的位都已加载给图像 ERROR 在加载过程中发生错误 FRAMEBITS 多帧图像的一个帧被传送,一般用于GIF HEIGHT 图像的高度已经可用 PROPERTIES 图像的属性已经可用 SOMEBITS 图像的缩放变体的多个位已经可用 WIDTH 图像的宽度已经可用参数 flags 的作用是通知图像观察者图像生产的进展情况。这些常数代表传递给 ImageObserver.imageUpdate() 的 flags 参数中的位。当 Component 作为 ImageObserver 时,一旦图像有新的部分被加载,就会调用 Component.imageUpdate() 方法,imageUpdate() 再调用 repaint() 重新绘制图像。repaint() 将先调用 update() 方法清除组件背景,再由 update() 方法调用 paint() 方法绘制图像。我们可以通过重载 imageUpdate() 方法控制组件何时被更新,重载 update() 方法控制是否每次重绘都要清除背景图像(每次重绘都清除背景图像会造成画面闪烁)。为了更好的理解,下面我们来看几个样例程序:例1,图像位在需要之前不被生产 500)this.width=500'>500){this.resized=true;this.style.width=500;}" align="top">import java.net.URL;500)this.width=500'>500){this.resized=true;this.style.width=500;}" align="top">import java.applet.Applet;500)this.width=500'>500){this.resized=true;this.style.width=500;}" align="top">import java.awt.Graphics;500)this.width=500'>500){this.resized=true;this.style.width=500;}" align="top">import java.awt.Image;500)this.width=500'>500){this.resized=true;this.style.width=500;}" align="top">500)this.width=500'>500){this.resized=true;this.style.width=500;}" align="top">500)this.width=500'>500){this.resized=true;this.style.width=500;}" align="top">public class ImageTestAppletSimple extends Applet500)this.width=500'>500){this.resized=true;this.style.width=500;}">{500)this.width=500'>500){this.resized=true;this.style.width=500;}" align="top">    private Image im;500)this.width=500'>500){this.resized=true;this.style.width=500;}" align="top">    500)this.width=500'>500){this.resized=true;this.style.width=500;}" align="top">500)this.width=500'>500){this.resized=true;this.style.width=500;}" align="top">    public void init()500)this.width=500'>500){this.resized=true;this.style.width=500;}">{500)this.width=500'>500){this.resized=true;this.style.width=500;}" align="top">        URL codebase = getCodeBase();500)this.width=500'>500){this.resized=true;this.style.width=500;}" align="top">        System.out.println(codebase);500)this.width=500'>500){this.resized=true;this.style.width=500;}" align="top">        500)this.width=500'>500){this.resized=true;this.style.width=500;}" align="top">        im = getImage(codebase,"flower.jpg");500)this.width=500'>500){this.resized=true;this.style.width=500;}" align="top">        500)this.width=500'>500){this.resized=true;this.style.width=500;}" align="top">        System.out.print("Image width = " + im.getWidth(this));500)this.width=500'>500){this.resized=true;this.style.width=500;}" align="top">        System.out.println(" hight = " + im.getHeight(this));500)this.width=500'>500){this.resized=true;this.style.width=500;}" align="top">    }500)this.width=500'>500){this.resized=true;this.style.width=500;}" align="top">    500)this.width=500'>500){this.resized=true;this.style.width=500;}" align="top">500)this.width=500'>500){this.resized=true;this.style.width=500;}" align="top">    public void paint(Graphics g)500)this.width=500'>500){this.resized=true;this.style.width=500;}">{500)this.width=500'>500){this.resized=true;this.style.width=500;}" align="top">        g.drawImage(im,0,0,this);500)this.width=500'>500){this.resized=true;this.style.width=500;}" align="top">    }500)this.width=500'>500){this.resized=true;this.style.width=500;}" align="top">} 输出结果:image width = -1 height = -1图像的高度和宽度只有在图像被完全加载后才是有效的,输出结果说明 java.awt.image 相关的图像位在需要之前不被生产。例2,图像异步生产 500)this.width=500'>500){this.resized=true;this.style.width=500;}" align="top">import java.net.URL;500)this.width=500'>500){this.resized=true;this.style.width=500;}" align="top">import java.applet.Applet;500)this.width=500'>500){this.resized=true;this.style.width=500;}" align="top">import java.awt.Graphics;500)this.width=500'>500){this.resized=true;this.style.width=500;}" align="top">import java.awt.Image;500)this.width=500'>500){this.resized=true;this.style.width=500;}" align="top">500)this.width=500'>500){this.resized=true;this.style.width=500;}" align="top">500)this.width=500'>500){this.resized=true;this.style.width=500;}" align="top">public class ImageTestAppletSimple2 extends Applet500)this.width=500'>500){this.resized=true;this.style.width=500;}">{500)this.width=500'>500){this.resized=true;this.style.width=500;}" align="top">    private Image im;500)this.width=500'>500){this.resized=true;this.style.width=500;}" align="top">    500)this.width=500'>500){this.resized=true;this.style.width=500;}" align="top">500)this.width=500'>500){this.resized=true;this.style.width=500;}" align="top">    public void init()500)this.width=500'>500){this.resized=true;this.style.width=500;}">{500)this.width=500'>500){this.resized=true;this.style.width=500;}" align="top">        im = getImage(getCodeBase(),"flower.jpg");500)this.width=500'>500){this.resized=true;this.style.width=500;}" align="top">    }500)this.width=500'>500){this.resized=true;this.style.width=500;}" align="top">    500)this.width=500'>500){this.resized=true;this.style.width=500;}" align="top">500)this.width=500'>500){this.resized=true;this.style.width=500;}" align="top">    public void paint(Graphics g)500)this.width=500'>500){this.resized=true;this.style.width=500;}">{500)this.width=500'>500){this.resized=true;this.style.width=500;}" align="top">        System.out.println("drawing image...");500)this.width=500'>500){this.resized=true;this.style.width=500;}" align="top">        System.out.println(g.drawImage(im,0,0,this));500)this.width=500'>500){this.resized=true;this.style.width=500;}" align="top">    }500)this.width=500'>500){this.resized=true;this.style.width=500;}" align="top">} 输出结果:drawing image...falsedrawing image...falsedrawing image...falsedrawing image...true输出结果说明组件作为 ImageObserver ,监视 ImageProducer 异步生产图像,一旦有新的图像位被生产时就重绘图像,图像完全加载后 drawImage() 方法返回 true。例3,重载 ImageObserver 的 imageUpdate() 方法,在图像完全加载前不调用 repaint() 500)this.width=500'>500){this.resized=true;this.style.width=500;}" align="top">import java.applet.Applet;500)this.width=500'>500){this.resized=true;this.style.width=500;}" align="top">import java.awt.Graphics;500)this.width=500'>500){this.resized=true;this.style.width=500;}" align="top">import java.awt.Image;500)this.width=500'>500){this.resized=true;this.style.width=500;}" align="top">500)this.width=500'>500){this.resized=true;this.style.width=500;}" align="top">500)this.width=500'>500){this.resized=true;this.style.width=500;}" align="top">public class ImageTestAppletWithUpdate extends Applet500)this.width=500'>500){this.resized=true;this.style.width=500;}">{500)this.width=500'>500){this.resized=true;this.style.width=500;}" align="top">    private Image im;500)this.width=500'>500){this.resized=true;this.style.width=500;}" align="top">    500)this.width=500'>500){this.resized=true;this.style.width=500;}" align="top">500)this.width=500'>500){this.resized=true;this.style.width=500;}" align="top">    public void init()500)this.width=500'>500){this.resized=true;this.style.width=500;}">{500)this.width=500'>500){this.resized=true;this.style.width=500;}" align="top">        im = getImage(getCodeBase(),"flower.jpg");500)this.width=500'>500){this.resized=true;this.style.width=500;}" align="top">        500)this.width=500'>500){this.resized=true;this.style.width=500;}" align="top">        System.out.print("Image width = " + im.getWidth(this));500)this.width=500'>500){this.resized=true;this.style.width=500;}" align="top">        System.out.println("hight = " + im.getHeight(this));500)this.width=500'>500){this.resized=true;this.style.width=500;}" align="top">    }500)this.width=500'>500){this.resized=true;this.style.width=500;}" align="top">    500)this.width=500'>500){this.resized=true;this.style.width=500;}" align="top">500)this.width=500'>500){this.resized=true;this.style.width=500;}" align="top">    public void paint(Graphics g)500)this.width=500'>500){this.resized=true;this.style.width=500;}">{500)this.width=500'>500){this.resized=true;this.style.width=500;}" align="top">        g.drawImage(im,0,0,this);500)this.width=500'>500){this.resized=true;this.style.width=500;}" align="top">    }500)this.width=500'>500){this.resized=true;this.style.width=500;}" align="top">    500)this.width=500'>500){this.resized=true;this.style.width=500;}" align="top">500)this.width=500'>500){this.resized=true;this.style.width=500;}" align="top">    public boolean imageUpdate(Image image,int flags,int x,int y,int w,int h)500)this.width=500'>500){this.resized=true;this.style.width=500;}">{500)this.width=500'>500){this.resized=true;this.style.width=500;}" align="top">        System.out.println("imageUpdate():x=" + x + ",y=" + y + ",w=" + w + ",h=" + h);500)this.width=500'>500){this.resized=true;this.style.width=500;}" align="top">        500)this.width=500'>500){this.resized=true;this.style.width=500;}" align="top">        if((flags & ALLBITS) == 0)500)this.width=500'>500){this.resized=true;this.style.width=500;}" align="top">            return true;500)this.width=500'>500){this.resized=true;this.style.width=500;}" align="top">        else500)this.width=500'>500){this.resized=true;this.style.width=500;}" align="top">500)this.width=500'>500){this.resized=true;this.style.width=500;}" align="top">        500)this.width=500'>500){this.resized=true;this.style.width=500;}">{500)this.width=500'>500){this.resized=true;this.style.width=500;}" align="top">            repaint();500)this.width=500'>500){this.resized=true;this.style.width=500;}" align="top">            return false;500)this.width=500'>500){this.resized=true;this.style.width=500;}" align="top">        }500)this.width=500'>500){this.resized=true;this.style.width=500;}" align="top">    }500)this.width=500'>500){this.resized=true;this.style.width=500;}" align="top">} 例4,重载  Component.update() 方法,被调用时不清除背景图像,直接调用 paint() 方法绘制图像,消除闪烁 500)this.width=500'>500){this.resized=true;this.style.width=500;}" align="top">import java.applet.Applet;500)this.width=500'>500){this.resized=true;this.style.width=500;}" align="top">import java.awt.Graphics;500)this.width=500'>500){this.resized=true;this.style.width=500;}" align="top">import java.awt.Image;500)this.width=500'>500){this.resized=true;this.style.width=500;}" align="top">500)this.width=500'>500){this.resized=true;this.style.width=500;}" align="top">500)this.width=500'>500){this.resized=true;this.style.width=500;}" align="top">public class ImageTestAppletWithSmoothDynamicUpdate extends Applet500)this.width=500'>500){this.resized=true;this.style.width=500;}">{500)this.width=500'>500){this.resized=true;this.style.width=500;}" align="top">    private Image im;500)this.width=500'>500){this.resized=true;this.style.width=500;}" align="top">    500)this.width=500'>500){this.resized=true;this.style.width=500;}" align="top">500)this.width=500'>500){this.resized=true;this.style.width=500;}" align="top">    public void init()500)this.width=500'>500){this.resized=true;this.style.width=500;}">{500)this.width=500'>500){this.resized=true;this.style.width=500;}" align="top">        im = getImage(getCodeBase(),"hl.jpg");500)this.width=500'>500){this.resized=true;this.style.width=500;}" align="top">        500)this.width=500'>500){this.resized=true;this.style.width=500;}" align="top">        System.out.print("Image width = " + im.getWidth(this));500)this.width=500'>500){this.resized=true;this.style.width=500;}" align="top">        System.out.println("hight = " + im.getHeight(this));500)this.width=500'>500){this.resized=true;this.style.width=500;}" align="top">    }500)this.width=500'>500){this.resized=true;this.style.width=500;}" align="top">    500)this.width=500'>500){this.resized=true;this.style.width=500;}" align="top">500)this.width=500'>500){this.resized=true;this.style.width=500;}" align="top">    public void paint(Graphics g)500)this.width=500'>500){this.resized=true;this.style.width=500;}">{500)this.width=500'>500){this.resized=true;this.style.width=500;}" align="top">        g.drawImage(im,0,0,this);500)this.width=500'>500){this.resized=true;this.style.width=500;}" align="top">    }500)this.width=500'>500){this.resized=true;this.style.width=500;}" align="top">    500)this.width=500'>500){this.resized=true;this.style.width=500;}" align="top">500)this.width=500'>500){this.resized=true;this.style.width=500;}" align="top">    public boolean imageUpdate(Image image,int flags,int x,int y,int w,int h)500)this.width=500'>500){this.resized=true;this.style.width=500;}">{500)this.width=500'>500){this.resized=true;this.style.width=500;}" align="top">        System.out.println("imageUpdate():x=" + x + ",y=" + y + ",w=" + w + ",h=" + h);500)this.width=500'>500){this.resized=true;this.style.width=500;}" align="top">        500)this.width=500'>500){this.resized=true;this.style.width=500;}" align="top">        repaint();500)this.width=500'>500){this.resized=true;this.style.width=500;}" align="top">        500)this.width=500'>500){this.resized=true;this.style.width=500;}" align="top">        if((flags & ALLBITS) == 0)500)this.width=500'>500){this.resized=true;this.style.width=500;}" align="top">            return true;500)this.width=500'>500){this.resized=true;this.style.width=500;}" align="top">        else500)this.width=500'>500){this.resized=true;this.style.width=500;}" align="top">            return false;500)this.width=500'>500){this.resized=true;this.style.width=500;}" align="top">    }500)this.width=500'>500){this.resized=true;this.style.width=500;}" align="top">    500)this.width=500'>500){this.resized=true;this.style.width=500;}" align="top">500)this.width=500'>500){this.resized=true;this.style.width=500;}" align="top">    public void update(Graphics g)500)this.width=500'>500){this.resized=true;this.style.width=500;}">{500)this.width=500'>500){this.resized=true;this.style.width=500;}" align="top">        paint(g);500)this.width=500'>500){this.resized=true;this.style.width=500;}" align="top">    }


阅读全文(1537) | 回复(0) | 编辑 | 精华
 



发表评论:
昵称:
密码:
主页:
标题:
验证码:  (不区分大小写,请仔细填写,输错需重写评论内容!)



站点首页 | 联系我们 | 博客注册 | 博客登陆

Sponsored By W3CHINA
W3CHINA Blog 0.8 Processed in 0.359 second(s), page refreshed 144786678 times.
《全国人大常委会关于维护互联网安全的决定》  《计算机信息网络国际联网安全保护管理办法》
苏ICP备05006046号