[Image] AWT使用ImageProducer/ImagConsumer模式加载和显示图像的原理
以前写过2篇关于AWT中图像加载显示方法的文章,最近又多了一些对于 ImageProducer / ImagConsumer 模式的一些理解,尝试着用文字总结了一下,接着还想再写一篇介绍 AWT 中图像过滤的原理和方法。你可能认为现在学习 AWT 中的成像方法对于开发中已经没有太大的意义,因为已经有了 Java 2D 和 JAI ,但是我在实际工作中感到还是无法完全离开 AWT,特别是在一些基本的应用上。而且我觉得理解 AWT 的 Producer / Consumer (push) model 对于理解 Java 2D 的 Immediate mode model 和 JAI 的 Pipeline (pull) model 的都是有好处的。因为水平有限,这方面学习资料相对也不丰富,我也不知道我的理解或想法是否完全正确或者表述清楚,感兴趣的朋友可以当作学习参考,希望能够和我联系进行进一步的讨论。
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 。
ImagConsumer
java.awt.image软件包中,ImageFilter(图像过滤器)和 PixelGrabber(像素抓取器)实现了 ImagConsumer 接口,是 ImagConsumer。
ImageProducer 和 ImagConsumer 的详细介绍请阅读 使用 ImageProducer / ImagConsumer 进行图像过滤
ImageObserver
ImageObserver接口中,定义了一个常数集合和一个方法:
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,图像位在需要之前不被生产
import java.applet.Applet;
import java.awt.Graphics;
import java.awt.Image;
public class ImageTestAppletSimple extends Applet{
private Image im;
public void init(){
URL codebase = getCodeBase();
System.out.println(codebase);
im = getImage(codebase,"flower.jpg");
System.out.print("Image width = " + im.getWidth(this));
System.out.println(" hight = " + im.getHeight(this));
}
public void paint(Graphics g){
g.drawImage(im,0,0,this);
}
}
输出结果:
image width = -1 height = -1
图像的高度和宽度只有在图像被完全加载后才是有效的,输出结果说明 java.awt.image 相关的图像位在需要之前不被生产。
例2,图像异步生产
import java.applet.Applet;
import java.awt.Graphics;
import java.awt.Image;
public class ImageTestAppletSimple2 extends Applet{
private Image im;
public void init(){
im = getImage(getCodeBase(),"flower.jpg");
}
public void paint(Graphics g){
System.out.println("drawing image...");
System.out.println(g.drawImage(im,0,0,this));
}
}
输出结果:
drawing image...
false
drawing image...
false
drawing image...
false
drawing image...
true
输出结果说明组件作为 ImageObserver ,监视 ImageProducer 异步生产图像,一旦有新的图像位被生产时就重绘图像,图像完全加载后 drawImage() 方法返回 true。
例3,重载 ImageObserver 的 imageUpdate() 方法,在图像完全加载前不调用 repaint()
import java.awt.Graphics;
import java.awt.Image;
public class ImageTestAppletWithUpdate extends Applet{
private Image im;
public void init(){
im = getImage(getCodeBase(),"flower.jpg");
System.out.print("Image width = " + im.getWidth(this));
System.out.println("hight = " + im.getHeight(this));
}
public void paint(Graphics g){
g.drawImage(im,0,0,this);
}
public boolean imageUpdate(Image image,int flags,int x,int y,int w,int h){
System.out.println("imageUpdate():x=" + x + ",y=" + y + ",w=" + w + ",h=" + h);
if((flags & ALLBITS) == 0)
return true;
else
{
repaint();
return false;
}
}
}
例4,重载 Component.update() 方法,被调用时不清除背景图像,直接调用 paint() 方法绘制图像,消除闪烁
import java.awt.Graphics;
import java.awt.Image;
public class ImageTestAppletWithSmoothDynamicUpdate extends Applet{
private Image im;
public void init(){
im = getImage(getCodeBase(),"hl.jpg");
System.out.print("Image width = " + im.getWidth(this));
System.out.println("hight = " + im.getHeight(this));
}
public void paint(Graphics g){
g.drawImage(im,0,0,this);
}
public boolean imageUpdate(Image image,int flags,int x,int y,int w,int h){
System.out.println("imageUpdate():x=" + x + ",y=" + y + ",w=" + w + ",h=" + h);
repaint();
if((flags & ALLBITS) == 0)
return true;
else
return false;
}
public void update(Graphics g){
paint(g);
}
}
posted @ 2005-10-11 10:35 leon 阅读(1051) | 评论 (3) | 编辑 收藏
相关推荐
使用文本方式(控制台输入输出)和使用图形方式(可以使用AWT或者SWING)来实现猜数游戏。 进入程序后,显示文本内容,提示用户输入1-100之间的数字,然后程序对其进行判断,用户根据系统提供的提示信息继续猜,...
搭建方法文档和插件---在eclipse下搭建swing/awt/swt开发环境的方法和插件
对照了解AWT与Swing的区别,能更好地理解GUI
java awt 可视化ui编程 Java awt ui界面设计教程
Awt/Swing简易版贪吃蛇源码,可正常运行,非常基础的一个Java小游戏。
什么是AWT 用AWT构建GUI 事件处理 AWT组件类库
1.熟悉Java图形用户界面的设计原理和程序结构; 2.能设计符合问题要求的图形用户界面程序; 3.熟悉Java AWT、swing组件的功能; 4.掌握常用组件的事件接口; 5.会应用AWT、swing组件进行应用程序设计。 二、实验内容...
绝对好资料!!!下载就不后悔!!! 抽象窗口工具包AWT (Abstract Window Toolkit) 是 API为Java 程序提供的建立图形用户界面GUI (Graphics User Interface)工具集,AWT可...图形和图像工具,包括形状、颜色和字体类
利用java AWT和JAI技术绘制生物图像的方法可以使在实验室中得到的生物实验数据自动转化为需要的图谱,并且图像的精确度高。绘制成的图像既可以保存在本地硬盘中,也可以在浏览器中以网页的形式展示出来供研究人员分析...
用java 的awt和swing 编辑的计算器,编辑的思路比较好,代码精简。实现计算器四则混合运算。
awt包java Android awt包java Android awt包java Android awt包java Android awt包java Android awt包java Android awt包java Android awt包java Android awt包java Android awt包java Android awt包java Android ...
appengine-awt是在Google AppEngine环境中使用的java.awt和javax.imageio包的纯Java实现。 该代码主要基于Apache Harmony和Apache Sanselan项目。 当前,该库提供了足够的功能,可以使用蜡染将svg文件转码为图像。...
java awt/swing做的很简单的弹球游戏,只实现了球在空间里传,算是java awt/swing的一个基础应用吧
使用Java AWT和Swing实现的计算器,其中的输入输出框为TextField,其余按钮均为JButton,可以实现加、减、乘、除、取反、求倒运算。
swing基础学习和awt的区别,swing基础学习和awt的区别swing基础学习和awt的区别swing基础学习和awt的区别
Swing可视化插件 jigloo_SWT_Swing可视化设计工具
在AWT中,除了支持多框架图像(如动画GIF)外,还支持加载和显示GIF图像文件格式和JPEG图像文件格式。由于图像的加载和显示是采用异步方式进行的,所以有大量的用于图像加载和显示的技术。在本章中,将全面对这些方法...
因为时间紧促,目前行为模式没有什么区别,但设计了简单的反应,例如在发现玩家之后会主动冲向玩家(设计了关于敌人是否发现玩家的hasFoundPlayer()方法放在npc类之中,并对其进行相关使用来实现),而不是机械性的...
实际开发中使用AWT的情况非常少,但是我们仍然有必要学习AWT。主要原因如下: 1. Swing是在AWT基础上构建的,事件模型和一些支持类(形状、颜色、字体)都一样。掌握AWT有利于后面学习SWING. Eclipse不是swing开发的,...
java计算器,swing和awt,可以实现+-*/和根号