330 likes | 615 Views
Introduction Multimedia Use of sound, image, graphics and video Makes applications “come alive” Introduction (cont.) We will focus on Image-manipulation basics Creating smooth animations Customizing animation applets Playing audio files (via AudioClip interface) Creating image maps
E N D
Introduction • Multimedia • Use of sound, image, graphics and video • Makes applications “come alive”
Introduction (cont.) • We will focus on • Image-manipulation basics • Creating smooth animations • Customizing animation applets • Playing audio files (via AudioClip interface) • Creating image maps
Loading, Displaying and Scaling Images • Demonstrate some Java multimedia capabilities • java.awt.Image • abstract class (cannot be instantiated) • Can represent several image file formats • e.g., GIF, JPEG and PNG • javax.swing.ImageIcon • Concrete class
Objects of class Image must be created via method getImage Objects of class ImageIcon may be created via ImageIcon constructor Method drawImage displays Image object on screen Overloaded method drawImage displays scaled Image object on screen 1 // LoadImageAndScale.java 2 // Load an image and display it in its original size 3 // and scale it to twice its original width and height. 4 // Load and display the same image as an ImageIcon. 5 6 // Java core packages 7 import java.applet.Applet; 8 import java.awt.*; 9 10 // Java extension packages 11 import javax.swing.*; 12 13 public class LoadImageAndScale extends JApplet { 14 private Image logo1; 15 private ImageIcon logo2; 16 17 // load image when applet is loaded 18 public void init() 19 { 20 logo1 = getImage( getDocumentBase(), "logo.gif" ); 21 logo2 = new ImageIcon( "logo.gif" ); 22 } 23 24 // display image 25 public void paint( Graphics g ) 26 { 27 // draw original image 28 g.drawImage( logo1, 0, 0, this ); 29 30 // draw image scaled to fit width of applet 31 // and height of applet minus 120 pixels 32 g.drawImage( logo1, 0, 120, 33 getWidth(), getHeight() - 120, this ); 34 LoadImageAndScale.javaLines 14 and 20Lines 15 and 21Line 28Lines 32-33
Method paintIcon displays ImageIcon object on screen 35 // draw icon using its paintIcon method 36 logo2.paintIcon( this, g, 180, 0 ); 37 } 38 39 } // end class LoadImageAndScale LoadImageAndScale.java(Part 2)Line 36Program Output Size of the applet: 340 x 340
Animating a Series of Images • Demonstrate animating series of images • Images are stored in array
Create array that stores series of ImageIcon objects 1 // LogoAnimator.java 2 // Animation a series of images 3 4 // Java core packages 5 import java.awt.*; 6 import java.awt.event.*; 7 8 // Java extension packages 9 import javax.swing.*; 10 11 public class LogoAnimator extends JPanel 12 implements ActionListener { 13 14 protected ImageIcon images[]; // array of images 15 16 protected int totalImages = 30, // number of images 17 currentImage = 0, // current image index 18 animationDelay = 50, // millisecond delay 19 width, // image width 20 height; // image height 21 22 protected String imageName = "deitel"; // base image name 23 protected Timer animationTimer; // Timer drives animation 24 25 // initialize LogoAnimator by loading images 26 public LogoAnimator() 27 { 28 initializeAnimation(); 29 } 30 31 // initialize animation 32 protected void initializeAnimation() 33 { 34 images = new ImageIcon[ totalImages ]; 35 LogoAnimator.javaLines 14 and 34
Load ImageIcon objects into array Override method paintComponent of class JPanel to display ImageIcons Timer invokes method actionPerformed every animationDelay (50) milliseconds 36 // load images 37 for ( int count = 0; count < images.length; ++count ) 38 images[ count ] = new ImageIcon( getClass().getResource( 39 "images/" + imageName + count + ".gif" ) ); 40 41 width = images[ 0 ].getIconWidth(); // get icon width 42 height = images[ 0 ].getIconHeight(); // get icon height 43 } 44 45 // display current image 46 public void paintComponent( Graphics g ) 47 { 48 super.paintComponent( g ); 49 50 images[ currentImage ].paintIcon( this, g, 0, 0 ); 51 currentImage = ( currentImage + 1 ) % totalImages; 52 } 53 54 // respond to Timer's event 55 public void actionPerformed( ActionEvent actionEvent ) 56 { 57 repaint(); // repaint animator 58 } 59 60 // start or restart animation 61 public void startAnimation() 62 { 63 if ( animationTimer == null ) { 64 currentImage = 0; 65 animationTimer = new Timer( animationDelay, this ); 66 animationTimer.start(); 67 } 68 else// continue from last image displayed 69 if ( ! animationTimer.isRunning() ) 70 animationTimer.restart(); LogoAnimator.java (Part 2)Lines 37-39Lines 46-52Lines 55-58 and 65
Method stop indicates that Timer should stop generating events 71 } 72 73 // stop animation timer 74 public void stopAnimation() 75 { 76 animationTimer.stop(); 77 } 78 79 // return minimum size of animation 80 public Dimension getMinimumSize() 81 { 82 return getPreferredSize(); 83 } 84 85 // return preferred size of animation 86 public Dimension getPreferredSize() 87 { 88 return new Dimension( width, height ); 89 } 90 91 // execute animation in a JFrame 92 public static void main( String args[] ) 93 { 94 // create LogoAnimator 95 LogoAnimator animation = new LogoAnimator(); 96 97 // set up window 98 JFrame window = new JFrame( "Animator test" ); 99 100 Container container = window.getContentPane(); 101 container.add( animation ); 102 103 window.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE ); 104 LogoAnimator.java (Part 3)Line 76
105 // size and display window 106 window.pack(); 107 Insets insets = window.getInsets(); 108 109 window.setSize( animation.getPreferredSize().width + 110 insets.left + insets.right, 111 animation.getPreferredSize().height + 112 insets.top + insets.bottom ); 113 114 window.setVisible( true ); 115 animation.startAnimation(); // begin animation 116 117 } // end method main 118 119 } // end class LogoAnimator LogoAnimator.java (Part 4)
import java.applet.Applet; import java.awt.Graphics; public class Anim1a extends Applet implements Runnable { int position = 0; int increment = 3; Thread t; public void start() { if (t == null) { t = new Thread(this); t.start(); } } public void stop() { if (t != null) { t.stop(); t = null; } } public void paint(Graphics g) { g.fillOval(5, 5 + position, 30, 30); }
public void run() { while (true) { try { Thread.sleep(50); } catch (InterruptedException e) {} position += increment; if (position > 50 || position < 0) increment = -increment; repaint(); } } }
import java.applet.Applet; import java.awt.Graphics; public class Anim1n extends Applet implements Runnable { int position = 0; int increment = 3; Thread t; public void start() { if (t == null) { t = new Thread(this); t.start(); } } public void stop() { t = null; } public void paint(Graphics g) { g.fillOval(5, 5 + position, 30, 30); } The version without deprecated stop() method if (t != null) { t.stop(); t = null; }
public void run() { Thread thisThread = Thread.currentThread(); while (t == thisThread) { try { Thread.sleep(50); } catch (InterruptedException e) {} position += increment; if (position > 50 || position < 0) increment = -increment; repaint(); } } }
import java.applet.Applet; import java.awt.Graphics; class Animation extends Thread { private Anim1c appl; private int increment = 3; Animation(Anim1c a) { appl = a; } public void run() { while (true) { try { Thread.sleep(50); } catch (InterruptedException e) {} appl.setpos(increment); if (appl.getpos() > 50 || appl.getpos() < 0) increment = -increment; appl.repaint(); } } }
public class Anim1c extends Applet { private int position = 0; private Thread t; public void start() { if (t == null) { t = new Animation(this); t.start(); } } public int getpos() { return position; } public void setpos(int a) { position += a; } public void stop() { if (t != null) { t.stop(); t = null; } } public void paint(Graphics g) { g.fillOval(5, 5 + position, 30, 30); } }
import java.applet.Applet; import java.awt.Graphics; class Animation extends Thread { private Applet appl; protected int increment = 3; protected int position = 0; protected int pause = 50; Animation(Applet a) { appl = a; } public void run() { while (true) { try { Thread.sleep(pause); } catch (InterruptedException e) {} position += increment; if (position > 50 || position < 0) increment = -increment; appl.repaint(); } } public void draw(Graphics g) { g.fillOval(5, 5 + position, 30, 30); } }
class Animation1 extends Animation { Animation1(Applet a) { super(a); increment = 2; pause = 60; } public void draw(Graphics g) { g.fillRect(40 + position, 25, 30, 30); } }
public class Anim2a extends Applet { private Animation t, t1; public void start() { if (t == null) { t = new Animation(this); t.start(); } if (t1 == null) { t1 = new Animation1(this); t1.start(); } } public void stop() { if (t != null) { t.stop(); t = null; } if (t1 != null) { t1.stop(); t1 = null; } } public void paint(Graphics g) { t.draw(g); t1.draw(g); } }
import java.applet.Applet; import java.awt.*; class Animation extends Thread { private Applet appl; private Color color; private int increment; private int which; private int position = 0; private int pause; Animation(Applet a, Color c, int which, int p, int in) { color = c; appl = a; pause = p; increment = in; this.which = which; } public void run() { while (true) { try { Thread.sleep(pause); } catch (InterruptedException e) {} position += increment; if (position > 100 || position < 0) increment = -increment; appl.repaint(); } } Double buffering to avoid flickering Further reading http://www.dgp.toronto.edu/~mjmcguff/learn/java/07-backbuffer/
public void draw(Graphics g) { g.setColor(color); if (which == 1) g.fillOval(5, 5 + position, 30, 30); else g.fillRect(40 + position, 25, 30, 30); } } Double Buffering
public class Anim2b extends Applet { privateAnimation t, t1; private Image img; // image buffer private Graphics gcopy; // graphics tool for the image buffer public void init() { img = createImage(getWidth(), getHeight()); gcopy = img.getGraphics(); } public void start() { if (t == null) { t = new Animation(this, Color.red, 1, 50, 3); t.start(); } if (t1 == null) { t1 = new Animation(this, Color.blue, 2, 60, 2); t1.start(); } } Double Buffering
public void stop() { if (t != null) { t.stop(); t = null; } if (t1 != null) { t1.stop(); t1 = null; } } // change update so that it calls paint without clearing surface // the default implementation of update() clears the background public void update(Graphics g) { paint(g); } public void paint(Graphics g) { gcopy.setColor(Color.white); gcopy.fillRect(0, 0, size().width, size().height); // prepare the image buffer t.draw(gcopy); // draw 1st object on the image offscreen buffer t1.draw(gcopy); // draw the 2nd object g.drawImage(img, 0, 0, this); // copy the offscreen buffer to// the applet display } } Double Buffering
Image Maps • Image map • Contains hot areas • Message appears when user moves cursor over these areas
Add MouseMotionListener for when mouse cursor exits applet area 1 // ImageMap.java 2 // Demonstrating an image map. 3 4 // Java core packages 5 import java.awt.*; 6 import java.awt.event.*; 7 8 // Java extension packages 9 import javax.swing.*; 10 11 public class ImageMap extends JApplet { 12 private ImageIcon mapImage; 13 14 private String captions[] = { "Common Programming Error", 15 "Good Programming Practice", 16 "Graphical User Interface Tip", "Performance Tip", 17 "Portability Tip", "Software Engineering Observation", 18 "Testing and Debugging Tip" }; 19 20 // set up mouse listeners 21 public void init() 22 { 23 addMouseListener( 24 25 new MouseAdapter() { 26 27 // indicate when mouse pointer exits applet area 28 public void mouseExited( MouseEvent event ) 29 { 30 showStatus( "Pointer outside applet" ); 31 } 32 33 } // end anonymous inner class 34 35 ); // end addMouseListener method call ImageMap.javaLines 23-35
Add MouseMotionListener for hot areas Test coordinates to determine the icon over which the mouse was positioned 36 37 addMouseMotionListener( 38 39 new MouseMotionAdapter() { 40 41 // determine icon over which mouse appears 42 public void mouseMoved( MouseEvent event ) 43 { 44 showStatus( translateLocation( 45 event.getX(), event.getY() ) ); 46 } 47 48 } // end anonymous inner class 49 50 ); // end addMouseMotionListener method call 51 52 mapImage = new ImageIcon( "icons.png" ); 53 54 } // end method init 55 56 // display mapImage 57 public void paint( Graphics g ) 58 { 59 mapImage.paintIcon( this, g, 0, 0 ); 60 } 61 62 // return tip caption based on mouse coordinates 63 public String translateLocation( int x, int y ) 64 { 65 // if coordinates outside image, return immediately 66 if ( x >= mapImage.getIconWidth() || 67 y >= mapImage.getIconHeight() ) 68 return ""; 69 ImageMap.java (Part 2)Lines 37-50Lines 63-76
70 // determine icon number (0 - 6) 71 int iconWidth = mapImage.getIconWidth() / 7; 72 int iconNumber = x / iconWidth; 73 74 // return appropriate icon caption 75 return captions[ iconNumber ]; 76 } 77 78 } // end class ImageMap ImageMap.java (Part 3)
Loading and Playing Audio Clips • Playing audio clips • Method play of class Applet • Method play of class AudioClip • Java’s sound engine • Supports several audio file formats • Sun Audio (.au) • Windows Wave (.wav) • Macintosh AIFF (.aif or .aiff) • Musical Instrument Digital Interface (MIDI) (.mid)
Declare three AudioClip objects 1 // LoadAudioAndPlay.java 2 // Load an audio clip and play it. 3 4 // Java core packages 5 import java.applet.*; 6 import java.awt.*; 7 import java.awt.event.*; 8 9 // Java extension packages 10 import javax.swing.*; 11 12 public class LoadAudioAndPlay extends JApplet { 13 private AudioClip sound1, sound2, currentSound; 14 private JButton playSound, loopSound, stopSound; 15 private JComboBox chooseSound; 16 17 // load the image when the applet begins executing 18 public void init() 19 { 20 Container container = getContentPane(); 21 container.setLayout( new FlowLayout() ); 22 23 String choices[] = { "Welcome", "Hi" }; 24 chooseSound = new JComboBox( choices ); 25 26 chooseSound.addItemListener( 27 28 new ItemListener() { 29 30 // stop sound and change to sound to user's selection 31 public void itemStateChanged( ItemEvent e ) 32 { 33 currentSound.stop(); 34 LoadAudioAndPlay.javaLine 13
Method getAudioClip loads audio file into AudioClip object 35 currentSound = 36 chooseSound.getSelectedIndex() == 0 ? 37 sound1 : sound2; 38 } 39 40 } // end anonymous inner class 41 42 ); // end addItemListener method call 43 44 container.add( chooseSound ); 45 46 // set up button event handler and buttons 47 ButtonHandler handler = new ButtonHandler(); 48 49 playSound = new JButton( "Play" ); 50 playSound.addActionListener( handler ); 51 container.add( playSound ); 52 53 loopSound = new JButton( "Loop" ); 54 loopSound.addActionListener( handler ); 55 container.add( loopSound ); 56 57 stopSound = new JButton( "Stop" ); 58 stopSound.addActionListener( handler ); 59 container.add( stopSound ); 60 61 // load sounds and set currentSound 62 sound1 = getAudioClip( getDocumentBase(), "welcome.wav" ); 63 sound2 = getAudioClip( getDocumentBase(), "hi.au" ); 64 currentSound = sound1; 65 66 } // end method init 67 LoadAudioAndPlay.java (Part 2)Lines 62-63
Method stop stops playing the audio clip Method play starts playing the audio clip Method loops plays the audio clip continually 68 // stop the sound when the user switches Web pages 69 public void stop() 70 { 71 currentSound.stop(); 72 } 73 74 // private inner class to handle button events 75 private class ButtonHandler implements ActionListener { 76 77 // process play, loop and stop button events 78 public void actionPerformed( ActionEvent actionEvent ) 79 { 80 if ( actionEvent.getSource() == playSound ) 81 currentSound.play(); 82 83 else if ( actionEvent.getSource() == loopSound ) 84 currentSound.loop(); 85 86 else if ( actionEvent.getSource() == stopSound ) 87 currentSound.stop(); 88 } 89 } 90 91 } // end class LoadAudioAndPlay LoadAudioAndPlay.java (Part 3)Line 71Line 81Line 84