| 
				 4.前景树的制作 
  为增加动画的立体感,使得前景中的鱼跳跃时能在树间穿过,我们从背景图中切“割出”一颗树。我们没有使用特别的图像处理软件,也不用复杂的图像分割算法,而用在Windows2000/XP自带的“画图”软件进行比较粗的剪切获得一幅图,见图8。 
 
  
图8 前景树制作(1) 
然后对这幅图的背景进行像素改变,用类Java语言表示,算法如下: 
if(red>=40&&red<=90&&green>=110&& 
green<=130&&blue>=100&&blue<=180){ 
  设置为白色且全透明; 
}        
else if(red==255&&green==255&&blue==255){ 
设置为全透明; 
} 
上述算法执行后,在内存中将形成如图9。在内存图9中,树是不透明的,其余白色区域是全透明的。 
 
 
  
图9 前景树制作(2) 
5.鱼的旋转 
  前景中的鱼在空中有一个旋转的动作,其代码解释如下。 
    (1) 先创建一个缓冲区图像 
Image filtIm=new BufferedImage(width,height, 
    BufferedImage.TYPE_INT_ARGB); 
  (2) 绕图像中心逆时针旋转60度 
AffineTransform transform= 
AffineTransform.getRotateInstance(  
Math.toRadians(-60),34,34); 
    (3) 创建仿射变换操作对像,用下面的方法 
AffineTransformOp op= 
new AffineTransformOp(transform,  
AffineTransformOp.TYPE_BILINEAR); 
其中transform为仿射变换对像,TYPE_ BILINEAR或TYPE_NEAREST_ NEIGHBOR是两个常量,与仿射变换中放大图像时有关。 
    (4) Java提供了许多过滤器执行常见的图像处理操作 
op.filter(buff,filtIm); 
关于仿射变换可参见文献[1, p.410]。 
6. 双缓冲技术的使用 
本程序使用双缓冲技术,首先定义空Image对像和空Graphcs对像: 
Image offIm=createImage(256,256); 
    Graphics offGr=offIm.getGraphics(); 
所有画图动作先在空图形对像offGr上进行,待所有画图动作完成后,一次性地将图像在屏幕上画出。关于双缓冲技术可阅[3]。 
7. 背景图像的层次 
程序运行中几幅图像作画的先后次序是重要的,否则,将不会产生立体感。正确的次序如下: 
  (1) 画背景图像imBack 
offGr.drawImage(imBack,0,0,this); 
(2) 画出fish图imgA 
offGr.drawImage(imgA,x,y,this); 
或旋转后的fish图filtIm 
  offGr.drawImage(filtIm,x,y-80,null); 
  (3) 将已改变透明度的云层、海水和一棵树画出 
offGr.drawImage(imBack1a,0,0,this); 
   offGr.drawImage(imBack2a,0,220,this);  
   offGr.drawImage(imTreea,0,0,this);    
  (4) 最后,一次性画出内存图像offIm 
g.drawImage(offIm,0,0,this); 
  
四、程序实例 
  
下面是整个程序的代码。其中的HTML文件已作为注释加入到程序代码中。 
/** 
* @moveImage.java 
 * @Author Xie-Hua Sun, 2008.01.05 
 */ 
import java.awt.*; 
import java.applet.*; 
import java.awt.event.*; 
import javax.swing.*; 
import java.awt.image.*; 
import java.awt.geom.*; 
/* 
 *<html> 
 *  <applet code=moveImage.class  
*         width=256 height=290> 
 *  </applet> 
 *</html> 
 **/ 
public class moveImage extends Applet implements ActionListener, Runnable { 
  BufferedImage buff,filtIm; //缓冲图像 
  Image offIm, 
        img,            //前景fish图 
        imgA,          //背景全透明的fish图 
        imBack,imBack1a, 
imBack2a,imTree,imTreea;         
  Graphics offGr,tempGr; 
     
  int iw,ih,              //宽、高 
     width,height,       //旋转fish图宽、高 
     pixels[];           //存储前景图像素 
  boolean  tFlag=true;   //动画运动标志 
  JButton  bStart, bStop; 
  Thread   thread; 
  AudioClip sound;  
   
  public void init() { 
    setLayout(new BorderLayout()); 
    setBackground(Color.lightGray); 
    Panel panel=new Panel(); 
    bStart=new JButton("开始"); 
    bStop =new JButton("停止"); 
    panel.add(bStart); panel.add(bStop); 
    this.add(panel,BorderLayout.SOUTH); 
    bStart.addActionListener(this); 
    bStop.addActionListener(this);  
    offIm=createImage(256,256); 
    offGr=offIm.getGraphics(); 
    loadImage();            //装载图像 			
				 |