how to set timer for capturing images from web cam?

180 views Asked by At

in my code having capture button it individually capturing image once but now i want set timer to capturing image per second

   package capturewebcam;
   import java.awt.Component;
   import java.awt.Image;
   import java.awt.image.BufferedImage;
   import java.io.File;
   import java.io.IOException;
   import java.util.logging.Level;
   import java.util.logging.Logger;
   import javax.imageio.ImageIO;
   import javax.media.Buffer;
   import javax.media.CannotRealizeException;
   import javax.media.Manager;
   import javax.media.MediaLocator;
   import javax.media.NoPlayerException;
   import javax.media.Player;
   import javax.media.control.FrameGrabbingControl;
   import javax.media.format.VideoFormat;
   import javax.media.util.BufferToImage;
   import javax.swing.JLabel;

   public class CaptureImage  {

   Player broadcast = null;
   Image img = null;

   public Component componen()throws IOException, NoPlayerException{
     Component comp_video;
     MediaLocator loo = new MediaLocator("vfw://0");
    try {
        broadcast = Manager.createRealizedPlayer(loo);
        broadcast.start();
    } catch (CannotRealizeException ex) {
        Logger.getLogger(CaptureImage.class.getName()).log(Level.SEVERE, null, ex);
    }
     if((comp_video = broadcast.getVisualComponent()) != null)
        {
            comp_video.setSize(322,315);
            return comp_video;

        }
     else{

    return null;
     }

   }
   public void capture_image(){
    FrameGrabbingControl grab = (FrameGrabbingControl)
    broadcast.getControl("javax.media.control.FrameGrabbingControl"); 
    Buffer buff = grab.grabFrame();
    BufferToImage image = new BufferToImage((VideoFormat)buff.getFormat());
    img = image.createImage(buff);

}
public void set_image_label(JLabel lb){
    capture_image();
    lb.setIcon(new javax.swing.ImageIcon(img));

  } 

    public void save_image(String path){
    BufferedImage image = (BufferedImage) img;
    File outputfile = new File(path);
    try {
        ImageIO.write(image, "png", outputfile);
    } catch (IOException ex) {
        Logger.getLogger(CaptureImage.class.getName()).log(Level.SEVERE, null, ex);
    }
  }

 }
1

There are 1 answers

0
Hovercraft Full Of Eels On BEST ANSWER

I would use a SwingWorker to do this since your capture_image() method likely will take enough time to complete as to possibly step on the Swing event thread, reducing the responsiveness of your program. Inside of your SwingWorker's doInBackground() method, you could use a for or while loop with a Thread.sleep(...) inside it, or you could use a java.util.Timer /TimerTask or a ScheduledExecutorService to repeatedly grab your images. You'd then transmit them back to the GUI using the SwingWorker's publish/process method pair. For more details on how to use a SwingWorker, please check out the SwingWorker Tutorial.

Perhaps something like,

private class MyImageWorker extends SwingWorker<Void, Icon> {
  private static final long SLEEP_DELAY = 1000;
  private volatile boolean doneLoadingImgs = false;

  public boolean isDoneLoadingImgs() {
     return doneLoadingImgs;
  }

  public void setDoneLoadingImgs(boolean doneLoadingImgs) {
     this.doneLoadingImgs = doneLoadingImgs;
  }

  @Override
  protected Void doInBackground() throws Exception {
     while (!doneLoadingImgs) {
        BufferedImage img = captureImage();
        ImageIcon icon = new ImageIcon(img);
        publish(icon);

        Thread.sleep(SLEEP_DELAY);
     }
     return null;
  }

  @Override
  protected void process(List<Icon> iconList) {
     for (Icon icon : iconList) {
        lb.setIcon(icon);
     }
  }

  private BufferedImage captureImage() {
     FrameGrabbingControl grab = (FrameGrabbingControl) broadcast
           .getControl("javax.media.control.FrameGrabbingControl");
     Buffer buff = grab.grabFrame();
     BufferToImage image = new BufferToImage((VideoFormat) buff.getFormat());
     BufferedImage img = image.createImage(buff);
     return img;
  }
}