在Windows下使用java语言打开摄像头【JMF版】

由于需要做一个自动拍照系统,所以在网上学习了使用java打开摄像头,很多人推荐javaCV,但是我不小心使用了JFM,所以先这样吧~~

在oracle网站下载window平台的JMF,如下图

在Windows下使用java语言打开摄像头【JMF版】_第1张图片

从图中I586可以看出,我们的jdk也必须要是32位的,(尝试发现64位的JDK将导致JMF无法检测出摄像头,至少在我的电脑上是的)

目前我的本机64位win7 +32位jdk1.8;

将jmf-2_1_1e-windows-i586.exe双击按照提示安装成功后,在你的JDK安装目录\jre\lib\ext下,会多出两个文件:jmf.jar和sound.jar

接着在JMF的安装目录下打开bin/jmfregistry.exe

在Windows下使用java语言打开摄像头【JMF版】_第2张图片

效果如下:

在Windows下使用java语言打开摄像头【JMF版】_第3张图片

可以看出这是还没有检测到摄像头

接着点击左下角的Detect Capture Devices

在Windows下使用java语言打开摄像头【JMF版】_第4张图片

点击确定后,摄像头依旧没出现,不知道什么原因(多点几次Detect Captur Devices就好了,并不是我一个人的电脑这样,很多人都这样的),最终效果如下

在Windows下使用java语言打开摄像头【JMF版】_第5张图片

OK,这时候,摄像头成功注册了。

接下来可以编写代码了,下边的代码是我从网上照的前辈写的(被我删掉了一部分),点击进入源码地址,源码好像有拍照功能,但是无论是使用源码还是使用下边这段精简版,都会存在找不到拍照按钮

import javax.swing.*;//使用swing库

import javax.swing.event.*;

import java.io.*;

import javax.media.*;

import javax.media.format.*;

import javax.media.util.*;

import javax.media.control.*;

import javax.media.protocol.*;

import java.util.*;

import java.awt.*;

import java.awt.image.*;

import java.awt.event.*;

import com.sun.image.codec.jpeg.*;


public class SwingCapture extends JPanel implements ActionListener//是JPanel里的子类,实现了ActionListener接口,动作侦听器

{

  public static Player player = null;//一个播放对象,目前为空

  public CaptureDeviceInfo di = null;//设备的配置信息

  public MediaLocator ml = null;//

  public JButton capture = null;//一个按钮

  public Buffer buf = null;

  public Image img = null;

  public VideoFormat vf = null;

  public BufferToImage btoi = null;

  public ImagePanel imgpanel = null;//声明一个相片图片容器,ImagePanel类在后边声明


  public SwingCapture()//构造函数,设置swing的外观风格。

  {

    this.setLayout(new BorderLayout());//设置布局,BorderLayout()一种布局管理器

    this.setSize(10,10);//设置面板大小,数字是像素点

    
    imgpanel = new ImagePanel();//相片图片容器


    capture = new JButton("Capture");//照相按扭

    capture.addActionListener(this);//使用窗体自身监听这个按扭

		capture.setSize(10,10);

		capture.setBackground(Color.BLUE);


    String str1 = "vfw:Logitech USB Video Camera:0";

    String str2 = "vfw:Microsoft WDM Image Capture (Win32):0";

    di = CaptureDeviceManager.getDevice(str2);//获得设备控制权

    ml= di.getLocator();//定位

   setLayout(new GridLayout(3,1));

    try

    {

      player = Manager.createRealizedPlayer(ml);//实现定位目标

      player.start();//开始实现

      Component comp;//创建一个组件


      if ((comp = player.getVisualComponent()) != null)// 可视组件不为空

      {

        add(comp);//增加到组件容器

      }

	add(imgpanel);

	add(capture);

    }

    catch (Exception e)

    {

      e.printStackTrace();

    }

  }


 public static void playerclose()//关闭窗体后,在exit程序之前,用于释放播放器资源

  {

    player.close();

    player.deallocate();//停止播放器后必须释放内存中的资源

  }


 public static void saveJPG(Image img, String s)//保存图片



  {

    BufferedImage bi = new BufferedImage(img.getWidth(null), img.getHeight(null), BufferedImage.TYPE_INT_RGB);//从buf中取得图片对像

    Graphics2D g2 = bi.createGraphics();//取得绘画图形工具

    g2.drawImage(img, null, null); //绘画图形

    FileOutputStream out = null;//创建存放文件流对像

    try

    {

      out = new FileOutputStream(s); //创建存放指定文件流路经对像

    }

    catch (java.io.FileNotFoundException io)

    {

      System.out.println("File Not Found");

    }

    JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out); //创建一个和指定输出流关联的JPEGImageEncoder对象

    JPEGEncodeParam param = encoder.getDefaultJPEGEncodeParam(bi); //此方法根据指定的压缩率浮点值

    param.setQuality(0.5f,false); //压缩大小为一半

    encoder.setJPEGEncodeParam(param);//将图片放进输出流

    try

    {

      encoder.encode(bi); //编码这个输出流 

      out.close();//关闭

    }

    catch (java.io.IOException io)

    {

      System.out.println("IOException");

    }

  }


  public static void main(String[] args)

  {

    JFrame f = new JFrame("SwingCapture");//创建一个窗体

    SwingCapture cf = new SwingCapture();//创建一个面板

		

    //给java做的图形界面添加关闭事件的时候,使用了WindowAdapter这个类				

    f.addWindowListener(new WindowAdapter() {

      public void windowClosing(WindowEvent e) {

      	playerclose();//

      	System.exit(0);

	 }
      }

    );
   

    f.add(cf,BorderLayout.CENTER);//向frame容器里输入swing风格中间大小帖的图片

    f.pack();//打包放进容器

    f.setSize(316,728);//设定JFrame的规格大小

		f.setResizable(false);

    f.setVisible(true); //显示一个Frame帖(没保存前先显示)

  } 

 

  public void actionPerformed(ActionEvent e)//此类的侦听部分

  {

    JComponent c = (JComponent) e.getSource();//创建一个绘画对像

    if (c == capture)//按拍照后

    {

      // Grab a frame

      FrameGrabbingControl fgc = (FrameGrabbingControl)//从视频轨迹中抽取当前帧对像

      player.getControl("javax.media.control.FrameGrabbingControl");//获取当前祯

      buf = fgc.grabFrame();//抓下来的图片放在buffer的中

     
      // Convert it to an image

      btoi = new BufferToImage((VideoFormat)buf.getFormat());//取得一个视频格式对像

      img = btoi.createImage(buf);//转化流格式 为图片格试


      // show the image

      imgpanel.setImage(img);//引用imgpanel面板显示图片 

     
      // save image

      saveJPG(img,"C:\\Users\\fujiaxiaoshao\\Desktop\\照片.jpg");//保存图片到本地硬盘

    }

  }

 
  class ImagePanel extends Panel//一个内部类,图片面板

  {

    public Image myimg = null;//创建一个图片对像

    public ImagePanel()

    {

      setLayout(null);//设置布局

      setSize(310,237);//设置布局大小

    }

   

    public void setImage(Image img)

    {

      this.myimg = img;

      repaint();//重绘

    }

   

    public void paint(Graphics g) //绘画图形

    {

      if (myimg != null)

      {

        g.drawImage(myimg, 0, 0, this); //绘画图形

      }

    }

  }

}

将代码存成如下文件:
在Windows下使用java语言打开摄像头【JMF版】_第6张图片

在命令行模式下编译并运行(如果安装JMF后没有重启PC将会报错,所以一定要重启),如下图:
在Windows下使用java语言打开摄像头【JMF版】_第7张图片
效果如下:

在Windows下使用java语言打开摄像头【JMF版】_第8张图片

拍摄成功的照片:
在Windows下使用java语言打开摄像头【JMF版】_第9张图片

PS:很多人会在ecliose中运行,会出现空指针报错,这应该是因为没有获取到摄像头驱动,应该 将jmf安装目录\lib目录下的jmf.jar,sound.jar,mediaplayer.jar三个文件导入工程,就可以正常运行了。

参考博客:http://my.oschina.net/hetiangui/blog/133189

http://blog.csdn.net/zajin/article/details/9288239    

http://zhangjunhd.blog.51cto.com/113473/25475

你可能感兴趣的:(在Windows下使用java语言打开摄像头【JMF版】)