In this post we will show how to use a USB camera to capture a picture from inside a Java application..
We will use the library LTI-CIVIL which is part of
FMJ (Freedom for Media in Java)
Let's go through the needed steps:
1.Download LTI-CIVIL:
Which is a Java library for capturing images from a video source such as a USB camera. It provides a simple API and does not depend on or use JMF!
The advantage behind this library that it doesn't depend on JMF (which is almost very old now)
The project URL:
http://lti-civil.org/
Download URL:
http://sourceforge.net/projects/lti-civil/files/
Extract the zip/tar file and you will find 2 things we will use:
a) lti-civil-no_s_w_t.jar
b) native folder contain the native libraries according to the operating system , pick the one for the system you are using.
2.Create the Java App:
Add to the class-path of the project the jar file and the native library folder.
To Run the project as jar file , you can use the JVM parameter:
-Djava.library.path=".....\native\win32-x86" to add the library to the class path of the jar file.
3.Create a class file:
Name it like TestWebCam implements CaptureObserver
4. Define the following instance variables:
JButton start = null;
JButton shot = null;
JButton stop = null;
CaptureStream captureStream = null;
boolean takeShot=false;
5.In the constructor:
Add the following code to initialize the capturing device:
public TestWebCam() {
CaptureSystemFactory factory = DefaultCaptureSystemFactorySingleton.instance();
CaptureSystem system;
try {
system = factory.createCaptureSystem();
system.init();
List list = system.getCaptureDeviceInfoList();
int i = 0;
if (i < list.size()) {
CaptureDeviceInfo info = (CaptureDeviceInfo) list.get(i);
System.out.println((new StringBuilder()).append("Device ID ").append(i).append(": ").append(info.getDeviceID()).toString());
System.out.println((new StringBuilder()).append("Description ").append(i).append(": ").append(info.getDescription()).toString());
captureStream = system.openCaptureDeviceStream(info.getDeviceID());
captureStream.setObserver(TestWebCam.this);
}
} catch (CaptureException ex) {
ex.printStackTrace();
}
//UI work of the program
JFrame frame = new JFrame();
frame.setSize(7000, 800);
JPanel panel = new JPanel();
frame.setContentPane(panel);
frame.setVisible(true);
frame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
start = new JButton("Start");
stop = new JButton("Stop");
shot = new JButton("Shot");
panel.add(start);
panel.add(stop);
panel.add(shot);
panel.revalidate();
start.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
try {
captureStream.start();
} catch (CaptureException ex) {
ex.printStackTrace();
}
}
});
stop.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
try {
captureStream.stop();
} catch (CaptureException ex) {
ex.printStackTrace();
}
}
});
shot.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
takeShot=true;
}
});
}
6.Add the following 2 methods mandated by the implemented interface CaptureObserver:
public void onNewImage(CaptureStream stream, Image image) {
if(!takeShot) return;
takeShot=false;
System.out.println("New Image Captured");
byte bytes[] = null;
try {
if (image == null) {
bytes = null;
return;
}
try {
ByteArrayOutputStream os = new ByteArrayOutputStream();
JPEGImageEncoder jpeg = JPEGCodec.createJPEGEncoder(os);
jpeg.encode(AWTImageConverter.toBufferedImage(image));
os.close();
bytes = os.toByteArray();
} catch (IOException e) {
e.printStackTrace();
bytes = null;
} catch (Throwable t) {
t.printStackTrace();
bytes = null;
}
if (bytes == null) {
return;
}
ByteArrayInputStream is = new ByteArrayInputStream(bytes);
File file = new File("/img" + Calendar.getInstance().getTimeInMillis() + ".jpg");
FileOutputStream fos = new FileOutputStream(file);
fos.write(bytes);
fos.close();
BufferedImage myImage = ImageIO.read(file);
shot.setText("");
shot.setIcon(new ImageIcon(myImage));
shot.revalidate();
} catch (IOException ex) {
ex.printStackTrace();
}
}
public void onError(CaptureStream stream, CaptureException ce) {
System.out.println("Error!");
}
7.Optionally, to Covert image to Gray Scale:
In case you need to convert it into Gray scale (for image processing purposes you can replace the following line with this block:
Old Line:
shot.setIcon(new ImageIcon(myImage));
New Block:
//Convert myImage to gray scale
BufferedImage imageGray = new BufferedImage(myImage.getWidth(), myImage.getHeight(),
BufferedImage.TYPE_BYTE_GRAY);
Graphics g = imageGray.getGraphics();
g.drawImage(myImage, 0, 0, null);
g.dispose();
shot.setIcon(new ImageIcon(imageGray));
8.Add main method to this class to run it:
public static void main(String args[])
throws Exception {
TestWebCam test = new TestWebCam();
}
9.Connect the USB Camera and run the application...
It should show 3 buttons : Start , Stop and Shot..
Click on start , then on shot, it will get you the current web camera image, move the web camera and take another shot by click on the picture to update it.
**Possible Issues:
1.Native library is not in the classpath.
2.Wrong native library is used.
3.USB Camera is not correct connected or installed.
4.Another program is running connected to the camera resource (you may be running your program 2 times)
You can use the CaptureStream parameter as well, but i think if you need to capture a streaming web cam , it would better to use images with intervals.
*** UPDATE: based on a lot of requests asking about using it to capture videos, here is the new post discussing the topic in details:
WebCam Video Capture in Java
Hope this help more to address this issue in particular.
*** UPDATE|: based on number of requests to access the web camera from JSP file , here is a link to a post discussing the how to in details:
Accessing Webcam Within JSP
*** UPDATE: if you want sample code , please download my other open source project Interactive4J, it has example for video and images.