如何设置从网络摄像头捕获图像的计时器?

时间:2014-11-15 16:30:36

标签: java swing timer netbeans-7

在我的代码中有捕获按钮它单独捕获图像一次,但现在我想设置定时器来捕获每秒图像

   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 个答案:

答案 0 :(得分:1)

我会使用SwingWorker来执行此操作,因为您的capture_image()方法可能需要足够的时间来完成,以便可能踩到Swing事件线程,从而降低程序的响应能力。在SwingWorker的doInBackground()方法内部,你可以在其中使用带有Thread.sleep(...)的for或while循环,或者你可以重复使用java.util.Timer / TimerTask或ScheduledExecutorService抓住你的图像。然后,您使用SwingWorker的发布/处理方法对将它们发送回GUI。有关如何使用SwingWorker的更多详细信息,请查看SwingWorker Tutorial

也许是这样的,

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;
  }
}