Presentation is loading. Please wait.

Presentation is loading. Please wait.

Java程序设计 第九章 多媒体与图形学程序设计 授课教师:赵小敏 浙江工业大学 软件学院 JAVA

Similar presentations


Presentation on theme: "Java程序设计 第九章 多媒体与图形学程序设计 授课教师:赵小敏 浙江工业大学 软件学院 JAVA"— Presentation transcript:

1 Java程序设计 第九章 多媒体与图形学程序设计 授课教师:赵小敏 浙江工业大学 软件学院 zxm@zjut.edu.cn JAVA
第九章 多媒体与图形学程序设计 JAVA 授课教师:赵小敏 浙江工业大学 软件学院 © 2005 赵小敏 Java Programming Java Programming

2 第9章补充 多媒体与图形学程序设计 主要内容: 一、声音播放 二、图像显示 三、图形处理 四、动画处理 © 2005 赵小敏
第9章补充 多媒体与图形学程序设计 主要内容: 一、声音播放 二、图像显示 三、图形处理 四、动画处理 © 2005 赵小敏 Java Programming

3 一、声音播放 1、加载声音文件 在Applet中播放声音十分简单,加载声音文件,然后调 用play方法播放即可。Java提供了两种播放声音的方式: 一种是通过Applet类的play方法,一种是通过 AudioClip接口中的方法来播放。Applet的play方法可 以将声音文件的加载与播放一并完成,其调用格式如下: void play(URL url) void play(URL url, String name) © 2005 赵小敏 Java Programming

4 加载声音文件 其中URL是一个网络地址,网络地址若包含声音文件 可采用第一种形式,否则采用第二种形式,播放本地计 算机上的声音文件也可采用第二种形式。假设有一个 MIDI声音文件trip.mid和Applet放在同一个目录下, 采用如下调用格式即可播放: play(getCodeBase( ),″trip.mid″); Applet的getAudioClip方法可创建这样的对象,该方 法加载指定网络地址的声音文件,并返回一个 AudioClip对象,调用格式如下: AudioClip getAudioClip(URL url) AudioClip getAudioClip(URL url, String name) © 2005 赵小敏 Java Programming

5 加载声音文件 创建AudioClip对象后,声音文件即被加载,可调用它 的方法处理声音文件。如果该方法没有找到指定的声 音文件,将返回null值,此时不能引用所创建的对象。 AudioClip只有3个方法: void play()播放一遍; void loop()连续播放; void stop()停止播放。 © 2005 赵小敏 Java Programming

6 本地计算机工作目录下有4个声音文件,代表 了.au 、 .mid、 .wav种声音格式,加载并播 放这些声音文件。结果如下图所示:
在Applet中播放声音 本地计算机工作目录下有4个声音文件,代表 了.au 、 .mid、 .wav种声音格式,加载并播 放这些声音文件。结果如下图所示: © 2005 赵小敏 Java Programming

7 例1程序源码: J_Audio.java import java.applet.*; import java.awt.*;
import java.awt.event.*; import javax.swing.*; public class J_Audio extends JApplet implements ActionListener, ItemListener{ private AudioClip m_soundFirst, m_soundSecond,m_soundThird, m_soundFourth, m_soundCurrent; private JButton m_buttonPlay, m_buttonLoop, m_buttonStop; private JComboBox m_comboChoose; public void init( ) // Build interfaces and set sounds{ Container container = getContentPane( ); container.setLayout( new FlowLayout( ) ); © 2005 赵小敏 Java Programming

8 String choices[] = { "hi", "bark","PINBALL","BATTVLOW" };
m_comboChoose = new JComboBox( choices ); m_comboChoose.addItemListener( this ); container.add( m_comboChoose ); m_buttonPlay = new JButton( "Play" ); m_buttonPlay.addActionListener( this ); container.add( m_buttonPlay ); m_buttonLoop = new JButton( "Loop" ); m_buttonLoop.addActionListener( this ); container.add( m_buttonLoop ); m_buttonStop = new JButton( "Stop" ); m_buttonStop.addActionListener( this ); container.add( m_buttonStop ); // load sounds and set m_soundCurrent m_soundFirst = getAudioClip( getDocumentBase( ), "hi.au" ); m_soundSecond = getAudioClip( getDocumentBase( ), "bark.au" ); m_soundThird = getAudioClip( getDocumentBase( ), "PINBALL.MID" ); m_soundFourth = getAudioClip( getDocumentBase( ), "BATTVLOW.WAV" ); m_soundCurrent = m_soundFirst; }

9 public void stop( ) { // Stop playing sound
m_soundCurrent.stop( ); } public void itemStateChanged( ItemEvent e ) { switch(m_comboChoose.getSelectedIndex( )){ case 0:m_soundCurrent=m_soundFirst;break; case 1:m_soundCurrent=m_soundSecond;break; case 2:m_soundCurrent=m_soundThird;break; case 3:m_soundCurrent=m_soundFourth;break; default:m_soundCurrent=m_soundFirst;break; public void actionPerformed(ActionEvent e){ if ( e.getSource( ) == m_buttonPlay ) m_soundCurrent.play( ); else if ( e.getSource( ) == m_buttonLoop ) m_soundCurrent.loop( ); else if ( e.getSource( ) == m_buttonStop ) } // End of method: actionPerformed

10 二、图像显示 Java支持两种图像格式JPEG和GIF。 JPEG称为联合图像专家组(joint photographic experts group),可用浏览器打开。JPEG(或JPG) 图像格式一般用来显示照片和具有连续色调的图 像,它能保存图像所有颜色信息。JPEG是一种压缩 的文件格式,在打开时自动解压缩。 GIF称为图像交换格式(graphic interchange format),可用浏览器打开。GIF图像是一种压缩 文件格式,由于它能最大限度地减少文件转换时间, 所以在HTML文件中常用于显示插图或图标。GIF 格式能有效减少文件大小,有利于在Internet上 使用,Java支持这种图像格式。 © 2005 赵小敏 Java Programming

11 1、加载图像 加载图像一般放在初始化方法init中进行。程序中 的getImage方法可加载Java支持的图像文件,它 有两个参数,一个是图像文件地址,一个是图像文 件名称。由于Applet是面向网络的,因此图像文件 的存储位置并不局限于本地计算机的磁盘目录,大 部分情况是直接读取Web服务器上的图像文件。 Java.applet.Applet的成员getImage方法返回 一个Image对象,它的调用格式为: Image getImage(URL url) Image getImage(URL url, String name) © 2005 赵小敏 Java Programming

12 2、显示图像 显示图像需要调用Graphics类的方法 drawImage,它可以将Image对象关联的图像显 示在Applet的指定位置。drawImage方法的调用 格式如下: boolean drawImage(Image img, int x, int y, ImageObserver observer) Color bgcolor, ImageObserver observer) © 2005 赵小敏 Java Programming

13 2、显示图像 其中img就是要显示的图像、x和y是图像显示位置(x 和y可取负值,表示一部分图像被移出了显示区)、 bgcolor是图像显示区域的背景色、observer是图像加 载跟踪器,通常将该参数指定为this,即由Applet负 责跟踪图像的加载情况。 这两种方法都是将图像照原样显示,能不能对图像进 行缩放呢?使用下面两种调用格式就可以对图像进行 缩放显示: boolean drawImage(Image img, int x, int y, int width, int height, ImageObserver observer) boolean drawImage(Image img, int x, int y, int w, int h, Color c, ImageObserver observer) © 2005 赵小敏 Java Programming

14 例2:显示图像 import java.awt.*; import javax.swing.*;
public class J_Image extends JApplet{ Image m_image[] = new Image[2]; public void init( ) { m_image[0]= getImage(getCodeBase( ), "ts1.gif"); m_image[1]= getImage(getCodeBase( ), "ts2.gif"); } // End of method: init public void paint(Graphics g){ g.drawImage(m_image[0], 0, 0, 150, 150, this); g.drawImage(m_image[1], 150, 0, 150, 150, this); g.drawImage(m_image[0], 0, 150, 300, 150, this); } // End of method: paint } // End of class: J_Image © 2005 赵小敏 Java Programming

15 运行结果 © 2005 赵小敏 Java Programming

16 3、幻灯机效果 如果Applet 仅仅是显示一幅图像,没有什么特别的 意义,不如直接在HTML文件中显示图像。Applet应 该做HTML做不到的事情,例如像幻灯机那样连续显 示图像。 多幅图像的显示,如下图: © 2005 赵小敏 Java Programming

17 例3:多幅图像的显示 for (int i=0; i<14; i++)
import java.awt.*; import java.awt.event.*; import java.applet.*; public class ShowDoggy extends Applet { int index; Image imgs[]=new Image[14]; public void init(){ addMouseListener(new MouseAdapter() { public void mouseClicked(MouseEvent e) { index=++index%6; repaint(); } }); for (int i=0; i<14; i++) imgs[i]=getImage(getCodeBase(),"doggy/T"+i+".gif"); } public void paint(Graphics g){ if (imgs[index]!=null) g.drawImage(imgs[index],20,20,this); © 2005 赵小敏 Java Programming

18 三、图形处理 基本的图形类: Color类:包含控制颜色的方法和常量 Font类:包含控制字体的方法和常量
Polygon类:包含创建多边形的方法 Graphis类:包含了绘制字符串、线条、矩形及其它形状的方法 Rectangle类:用来绘制矩形 java.awt.geom.CubicCurve2D.Double类:画抛物线 java.awt.geom.Arc2D.Double 类:画圆弧 java.awt.geom.Ellipse2D.Double 类:画椭圆 © 2005 赵小敏 Java Programming

19 图形环境和图形对象 在java中,图形环境使得可以在屏幕上绘图,对各种 图形的显示通过类Graphics和Graphics2D来完成。
Component类的paint方法以一个Graphics对象作为参 数,在Component执行paint操作时,系统将Graphics 对象传送给paint方法。 public void paint(Graphics g) © 2005 赵小敏 Java Programming Java Programming

20 Java API提供Color类定义颜色的方法和常量。
颜色控制 Java API提供Color类定义颜色的方法和常量。 每种颜色都是由红、绿和篮三种颜色组成,称为 RGB值。一个RGB值由三个部分,是0~255的整数 或0.0~1.0的浮点数。RGB值越大,相应颜色的含 量越大。 例4:使用几种不同的颜色绘制填充矩形和字符串 © 2005 赵小敏 Java Programming

21 字体控制 Java API提供Font类定义字体的方法和常量。 Font类的构造函数有三个参数:字体名称、字体风格和 字体大小。
字体名称可以是运行程序的系统所支持的任何一种字体, 如Java字体Monospaced,SansSerif和Serif 字体风格可以是Font.PLAIN,Font.ITALIC和Font.BOLD, 字体风格可以组合使用,如Font.ITALIC+Font.BOLD 字体大小是以点来衡量的,一个点是1/21英寸 注意:制定一个系统不存在的字体是一种逻辑错误。 © 2005 赵小敏 Java Programming

22 例5:显示4种不同大小、不同字体的文本 public void paint( Graphics g ) {
g.setFont( new Font( "Serif", Font.BOLD, 12 ) ); g.drawString( "Serif 12 point bold.", 20, 50 ); g.setFont( new Font( "Monospaced", Font.ITALIC, 24 ) ); g.drawString( "Monospaced 24 point italic.", 20, 70 ); g.setFont( new Font( "SansSerif", Font.PLAIN, 14 ) ); g.drawString( "SansSerif 14 point plain.", 20, 90 ); g.setColor( Color.red ); g.setFont( new Font( "Serif", Font.BOLD + Font.ITALIC, 18 ) ); g.drawString( g.getFont().getName() + " " + g.getFont().getSize() + " point bold italic.", 20, 110 ); } © 2005 赵小敏 Java Programming

23 画线、矩形和椭圆 例6:线、矩形、3D矩形、圆角矩形和椭圆的绘制。 public void paint( Graphics g ) {
g.setColor( Color.red ); g.drawLine( 5, 30, 350, 30 ); g.setColor( Color.blue ); g.drawRect( 5, 40, 90, 55 ); g.fillRect( 100, 40, 90, 55 ); g.setColor( Color.cyan ); g.fillRoundRect( 195, 40, 90, 55, 50, 50 ); g.drawRoundRect( 290, 40, 90, 55, 20, 20 ); g.setColor( Color.yellow ); g.draw3DRect( 5, 100, 90, 55, true ); g.fill3DRect( 100, 100, 90, 55, false ); g.setColor( Color.magenta ); g.drawOval( 195, 100, 90, 55 ); g.fillOval( 290, 100, 90, 55 ); } © 2005 赵小敏 Java Programming

24 画圆弧 弧形是椭圆的一部分,弧的角度以度来衡量。例7: 演示drawArc和fillArc。
public void paint( Graphics g ){ // start at 0 and sweep 360 degrees g.setColor( Color.yellow ); g.drawRect( 15, 35, 80, 80 ); g.setColor( Color.black ); g.drawArc( 15, 35, 80, 80, 0, 360 ); // start at 0 and sweep 110 degrees g.drawRect( 100, 35, 80, 80 ); g.drawArc( 100, 35, 80, 80, 0, 110 ); // start at 0 and sweep -270 degrees g.drawRect( 185, 35, 80, 80 ); g.drawArc( 185, 35, 80, 80, 0, -270 ); g.fillArc( 15, 120, 80, 40, 0, 360 ); // start at 270 and sweep -90 degrees g.fillArc( 100, 120, 80, 40, 270, -90 ); g.fillArc( 185, 120, 80, 40, 0, -270 ); } © 2005 赵小敏 Java Programming

25 例8:画多边形和折线 public void paint( Graphics g ) {
int xValues[] = { 20, 40, 50, 30, 20, 15 }; int yValues[] = { 50, 50, 60, 80, 80, 60 }; Polygon poly1 = new Polygon( xValues, yValues, 6 ); g.drawPolygon( poly1 ); int xValues2[] = { 70, 90, 100, 80, 70, 35, 60 }; int yValues2[] = { 100, 100, 110, 110, 130, 110, 90 }; g.drawPolyline( xValues2, yValues2, 7 ); int xValues3[] = { 120, 140, 150, 190 }; int yValues3[] = { 40, 70, 80, 60 }; g.fillPolygon( xValues3, yValues3, 4 ); Polygon poly2 = new Polygon(); poly2.addPoint( 165, 135 ); poly2.addPoint( 175, 150 ); poly2.addPoint( 270, 200 ); poly2.addPoint( 200, 220 ); poly2.addPoint( 130, 180 ); g.fillPolygon( poly2 ); } © 2005 赵小敏 Java Programming

26 结果显示 (70,100) (90,100) (100,110) (60,90) (65,110) (80,110) (70,130) © 2005 赵小敏 Java Programming

27 Java2D API Java2D API提供绘制复杂图形的二维图形功能类,具体 在以下包中: java.awt.*
java.awt.image.* java.awt.color.* java.awt.font.* java.awt.geom.* java.awt.print.* java.awt.image.renderable © 2005 赵小敏 Java Programming

28 Java2D图形 java.awt.geom包中提供一 些Java2D图形功能的类, 包括Ellipse2D.Double, Rectangle2D.Double, RoundRectangle2D.Double ,Arc2D.Double和 Line2D.Double等。 例9:演示几种Java2D图形 和绘制的特性 例10:绘制五角星 © 2005 赵小敏 Java Programming

29 游戏软件的设计中,动画向程序员提出了挑战,但在 Java中实现动画则是十分简单的事情。
四、动画处理 游戏软件的设计中,动画向程序员提出了挑战,但在 Java中实现动画则是十分简单的事情。 下面让我们一起由浅入深地编写几个动画程序实例,并 通过对这些实例的逐步改进来探讨Java动画技术的关 键。 © 2005 赵小敏 Java Programming

30 1、动画原理 计算机动画原理十分简单,首先在屏幕上显示出 第一帧画面,过一会儿把它擦掉,然后再显示下一 帧画面,如此循环往复。由于人眼存在着一个视觉 差,所以感觉好像画面中的物体在不断运动。 © 2005 赵小敏 Java Programming

31 例11:宇宙飞船游太空 try { Thread.sleep(30); x+=5; if (x==400) { x=0;
import java.awt.*; import java.applet.*; public class MovingImg extends Applet { Image star, rocket; int x=0; public void init() { star=getImage(getCodeBase(),"starfield.gif"); rocket=getImage(getCodeBase(),"rocketship.gif"); } public void paint(Graphics g) { g.drawImage(star,0,0,this); g.drawImage(rocket,x,15,this); try { Thread.sleep(30); x+=5; if (x==400) { x=0; Thread.sleep(600); } } catch (InterruptedException e) {} repaint(); © 2005 赵小敏 Java Programming

32 程序分析(1) 这是一个很简单的动画,在Applet中有一个充当太空的 背景图,一艘宇宙飞船在太空图上不断从左边移动到右 边。
程序中创建了两个Image对象star和rocket,在init方 法中分别加载了两个图像文件和这两个对象关联起来。 添加了变量x用来指定飞船的画出位置,x初始化为10。 在paint方法中,注意到太空总是画在指定位置(0, 0), 而飞船则画在位置(x, 15),其中x的值是不断变化的。 © 2005 赵小敏 Java Programming

33 程序分析(2) 真正使飞船实现动画效果是在try...catch块中。
paint方法的最后一条语句是调用repaint方法。repaint方 法的功能是重画图像,它先调用update方法将显示区清空, 再调用paint方法画出图像。这就形成了一个循环,paint调 用了repaint,而repaint又调用了paint,使飞船不间断地 来回移动。 运行这个Applet时,画面有闪烁现象。一般来说,画面越大, update以背景色清除显示区所占用的时间就越长,不可避 免地会产生闪烁。为了达到平滑而又没有闪烁的动画效果, 就应该考虑采取一些补救措施。 覆盖update方法可以降低闪烁,但不能消除它。能有效消 除闪烁的方法是采用图形双缓冲技术(graphics double buffering)。 © 2005 赵小敏 Java Programming

34 2、图形双缓冲技术 例12:改进后的宇宙飞船游太空 try { Thread.sleep(10); x+=2; if (x==400) {
import java.awt.*; import java.applet.*; public class MovingImg extends Applet { Image star, rocket, buffer; Graphics gContext; int x=10; public void init() { star=getImage(getCodeBase(),"starfield.gif"); rocket=getImage(getCodeBase(),"rocketship.gif"); buffer=createImage(getWidth(),getHeight()); gContext=buffer.getGraphics(); } public void paint(Graphics g) { gContext.drawImage(star,0,0,this); gContext.drawImage(rocket,x,15,this); g.drawImage(buffer,0,0,this); try { Thread.sleep(10); x+=2; if (x==400) { x=10; Thread.sleep(1000); } catch (InterruptedException e) {} repaint(); public void update(Graphics g) { paint(g); © 2005 赵小敏 Java Programming

35 3、用线程实现动画 例12用图形双缓冲改善了图像闪烁问题,但仍存在一 些其他问题。例如用户离开网页后,嵌入的Applet会继 续运行,占用CPU时间。下面的例13出于网络实用的目 的,采用独立线程实现动画。 © 2005 赵小敏 Java Programming

36 import java.awt.*; import java.applet.*; public class Running extends Applet implements Runnable { Image img[]=new Image[14]; Image buffer; Graphics gContext; Thread animate; int index=0; public void init() { buffer=createImage(getWidth(),getHeight()); gContext=buffer.getGraphics(); for (int i=0;i<14;i++) img[i]=getImage(getCodeBase(),"doggy/T"+i+".gif"); } public void start() { if (animate==null) { animate=new Thread(this); animate.start();

37 public void stop() { if (animate!=null) animate=null; } public void run() { while(true) { gContext.drawImage(img[index],100,20,this); repaint(); try { animate.sleep(200); } catch (InterruptedException e) {} gContext.clearRect(100,20,100,100); index=++index%10; public void paint(Graphics g) { g.drawImage(buffer,0,0,this); public void update(Graphics g) { paint(g);

38 例13程序分析(1) 本程序加载了14个图像(T0.gif~T13.gif),采用了图 形双缓冲技术,实现了Runnable接口中的run方法, 这是一个和Applet同时运行的线程。对线程的控制由 Applet的start和stop方法完成,Applet运行时,就在 start方法中启动线程,Applet停止时,就在stop方法 中停止线程。 对图像的操作全部放在run方法的永恒循环当中。首先 调用gContext的drawImage方法把当前图像画在屏 幕缓冲区内,怎样把它显示在屏幕上呢?是在paint方 法中把屏幕缓冲区拷贝到屏幕上。但paint方法一般无 法直接调用,因为要传递给它一个图形参数,所以通过 调用repaint方法来间接调用paint以完成屏幕拷贝。 © 2005 赵小敏 Java Programming

39 例13程序分析(2) repaint方法无参数,它将调用update方法,由 update方法调用paint方法并传递g参数。这就是我们 曾介绍过的一个线程负责准备图像而另一个线程负责 显示图像的动画方法。接下来,线程休眠50毫秒,然后 清除屏幕缓冲区中的图像,将图像下标加1并取模。如 果不清除屏幕缓冲区中的图像,将会出现图像重叠。下 标加1后求余数,可保证取值范围总是0~9。 © 2005 赵小敏 Java Programming

40 Thank You… Any ?? © 2005 赵小敏 Java Programming


Download ppt "Java程序设计 第九章 多媒体与图形学程序设计 授课教师:赵小敏 浙江工业大学 软件学院 JAVA"

Similar presentations


Ads by Google