由于需要,本人最近正在自学jmf。在利用jmf拍照时遇到了许多问题不过最后解决了,所以写了这篇博客,希望不管对自己还是对其他人或多或少有一点帮助吧。
在最开始安装jmf时我就遇到了问题,由于我的电脑的系统是win8的,所以我安装的jdk是64位的。很不幸的是安装jmf所需要的jdk必须是32位的,刚开始还不知道苦苦纠结了很久。后来本来想把64位的jdk卸载掉再安装32位的,但后来一想也许可以两个jdk装在一台电脑上,问别人有的人说可以有的说不行,所以我就干脆试一试,结果还真可以。只要
在JAVA_HOME里面把两个jdk的地址都加进去就可以了,安装过程并没有出现什么问题。
安装完32位的jdk自然就需要32为的eclipse了,怎么安装相信我就不必说了。
这些弄完之后自然就是码代码了
package MyCapturer;
import java.io.*;
import javax.media.*;
import javax.media.Buffer;
import javax.media.format.*;
import javax.media.util.*;
import javax.media.control.*;
import java.awt.*;
import java.awt.image.*;
import com.sun.image.codec.jpeg.*;
public class MyCapturer implements Runnable
{
public static Player player=null;
private CaptureDeviceInfo di=null;
private MediaLocator ml=null;
private Buffer buf=null;
private Image img=null;
private VideoFormat vf=null;
private BufferToImage btoi=null;
String str="vfw:Microsoft WDM Image Capture (Win32):0";
private int rectX;
private int rectY;
private int rectWidth=300;
private int rectHeight=200;
private int imgWidth=320;
private int imgHeight=240;
Thread thread=null;
public MyCapturer()
{
thread=new Thread(this); //建立专门的线程
di=CaptureDeviceManager.getDevice(str);
ml=di.getLocator();
try
{
player=Manager.createRealizedPlayer(ml);
}
catch(Exception e)
{
e.printStackTrace();
}
player.start();
thread.start();
sleep(500);
System.out.println("init OK");
}
public static void playerclose()
{
player.close();
player.deallocate();
}
public void capture()
{
FrameGrabbingControl fgc=(FrameGrabbingControl)player.getControl("javax.media.control.FrameGrabbingControl");
buf=fgc.grabFrame();// Convert it to an image
btoi=new BufferToImage((VideoFormat)buf.getFormat());
img=btoi.createImage(buf);// show the image
sleep(2000);
if(img==null)
{
System.out.println("capture Error");
System.exit(1);
}
System.out.println("capture OK");
}
public void save(String path)
{
if(img!=null)
{
saveJPG(path);
}
}
public void saveJPG(String s)
{
System.out.println("save start");
BufferedImage bi=new BufferedImage(img.getWidth(null),img.getHeight(null),BufferedImage.TYPE_INT_RGB);
Graphics2D g2=bi.createGraphics();
g2.clipRect(rectX,rectY,rectWidth,rectHeight);
g2.drawImage(img,null,null);
int moveX=rectX>0 ? rectX:0;
int moveY=rectY>0 ? rectY:0;
int cutWidth=rectX+rectWidth>imgWidth ? rectWidth-((rectX+rectWidth)-imgWidth):rectWidth;
int cutHeight=rectY+rectHeight>imgHeight ? rectHeight-((rectY+rectHeight)-imgHeight):rectHeight;
bi=bi.getSubimage(moveX,moveY,cutWidth,cutHeight);
File f=new File(s);
if(!f.exists())
try
{
f.createNewFile();
}
catch(IOException e)
{
e.printStackTrace();
}
FileOutputStream out=null;
try
{
out=new FileOutputStream(f);
}
catch(java.io.FileNotFoundException io)
{
System.out.println("File Not Found");
}
JPEGImageEncoder encoder=JPEGCodec.createJPEGEncoder(out);
JPEGEncodeParam param=encoder.getDefaultJPEGEncodeParam(bi);
param.setQuality(1f,false);
encoder.setJPEGEncodeParam(param);
try
{
encoder.encode(bi);
out.close();
System.out.println("save OK");
}
catch(java.io.IOException io)
{
System.out.println("IOException");
}
}
private void sleep(int t)
{
try
{
Thread.sleep(t);
}
catch(InterruptedException e)
{
e.printStackTrace();
}
}
public static void main(String[] args) throws Exception
{
int num=1;
MyCapturer m=new MyCapturer();
for(int i=0;i<3;i++)//利用for循环控制拍照次数
{
m.capture();
m.save("D:\\new"+num+".jpg");
System.out.println("picture "+num+" OK");
num++;
}
System.out.println("OK");
System.exit(0);
}
public void run()
{
// TODO Auto-generated method stub
sleep(500);
}
}
运行之后出现一个很奇怪的现象,第一次可以运行,第二次后就说找不到摄像头了,然后下面一大堆报错。在这里我纠结了很久,开始以为是我的代码写错了,后来在网上查找了很多类似的文章,仔细一琢磨发现问题可能不是在代码上,很有可能是win8系统的摄像头的驱动和jmf不兼容。所以我下载了一个虚拟摄像头,于是问题解决了,只不过每次运行都要选择摄像头。