Capture images from a gstreamer Pipeline - java

I have a IP camera that uses the RTSP protocol to transmit images, the following code uses gstreamer to connect, pick up those images and show in Swing (works just right).
What I want to do is pick up the frames direct from the Pipeline of gstreamer (not use Swing), so that I can analyze frame by frame the image.
import java.awt.BorderLayout;
import java.awt.Dimension;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
import org.gstreamer.Element;
import org.gstreamer.Gst;
import org.gstreamer.Pipeline;
import org.gstreamer.State;
import org.gstreamer.swing.VideoComponent;
public class Main {
public static void main(String[] args) throws InterruptedException {
args = Gst.init("PipelineLauncher", args);
final String def = "rtspsrc location=rtsp://192.168.25.160/av0_0 latency=0 ! decodebin ! ffmpegcolorspace name=testp";
final Pipeline pipe = Pipeline.launch(def);
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
// Create the video component and link it in
VideoComponent videoComponent = new VideoComponent();
Element videosink = videoComponent.getElement();
pipe.add(videosink);
pipe.getElementByName("testp").link(videosink);
pipe.setState(State.PAUSED);
if (pipe.isPlaying()) {
System.out.println("Pipeline playing");
} else {
System.out.println("Pipeline not playing");
}
// Start the pipeline processing
pipe.play();
pipe.setState(State.PLAYING);
if (pipe.isPlaying()) {
System.out.println("Pipeline playing");
} else {
System.out.println("Pipeline not playing");
}
// Now create a JFrame to display the video output
JFrame frame = new JFrame("Swing Video Test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(videoComponent, BorderLayout.CENTER);
videoComponent.setPreferredSize(new Dimension(800, 600));
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
Gst.main();
pipe.setState(State.NULL);
}
}

I suggest using a pad probe (http://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer/html/GstPad.html#gst-pad-add-probe). It will then trigger a callback with the buffer that is about to go through the pad. So you can put this at the pad you are most interested in in the pipeline (encoded RTP data or uncompressed raw image for example).
If you are just interested in the final data the appsink is also a good place to look at (http://gstreamer.freedesktop.org/data/doc/gstreamer/head/gst-plugins-base-libs/html/gst-plugins-base-libs-appsink.html).
In case of appsink and if you want to display the image and also want the data you may use a tee element (http://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer-plugins/html/gstreamer-plugins-tee.html).

You can use appsink to get the buffers from a pipeline.
http://gstreamer.freedesktop.org/data/doc/gstreamer/head/gst-plugins-base-libs/html/gst-plugins-base-libs-appsink.html

Related

How to refresh/reload an image in Swing GUI as the real image file changes?

I am trying to implement Remote FrameBuffer Protocol using Java socket programming.
I have a server side program that takes screenshot of the entire screen using robot and store it in BufferedImage .Then I converted it into a byte array and sending it to the client .
Objective :
To display the entire screen of the server side machine in a Swing GUI of the client side.
Problem i am facing :
i am able to send the image in bytes from server and receive it from the server by the client (client.java) and convert it into a jpg image (output.jpg) using ImageIO and put that image in a Swing frame.
But i am able to see the first image in the Swing and whenever the image gets updated ,the image in the Swing is not updating or refreshing .
What I want :
I want the image to refresh and show updated image every time the server sends the image data .
client.java
package remoteclient;
import java.lang.*;
import javax.imageio.*;
import java.awt.*;
import java.awt.image.BufferedImage;
import javax.swing.*;
import java.net.*;
import java.io.*;
public class client {
public static void main(String args[])throws Exception{
Socket s=new Socket("localhost",5900);
DataInputStream din=new DataInputStream(s.getInputStream());
DataOutputStream dout=new DataOutputStream(s.getOutputStream());
BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
int width=0,height=0;
try {
width = din.readInt(); //getting width and height from server thru socket.
height = din.readInt();
} catch (Exception e) {
e.printStackTrace();
}
JFrame f = new JFrame("Client");
JLabel label = new JLabel();
f.setSize(width, height);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setVisible(true);
boolean continueLoop = true;
while(continueLoop)
{
try {
int len = din.readInt();
byte[] imageInByte = new byte[len];
System.out.println(len);
din.readFully(imageInByte);
System.out.println(imageInByte);
ByteArrayInputStream bis = new ByteArrayInputStream(imageInByte);
BufferedImage bImage2 = ImageIO.read(bis);
// Image im1 = bImage2.getScaledInstance(width,height, Image.SCALE_SMOOTH);
ImageIO.write(bImage2, "jpg", new File("output.jpg") );
bImage2 = ImageIO.read(new File("output.jpg"));
label.setIcon(new ImageIcon(im1));
ImageIcon icon = new ImageIcon(bImage2);
icon.getImage().flush();
label.setIcon( icon );
f.getContentPane().add(label, BorderLayout.CENTER);
f.pack();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
What I want :
I want the image to refresh and show updated image every time the server sends the image data .
Updated code with comments about demo code that should be removed from your working code:
Here's an example, using default UIManager icons, and SwingWorker, as noted in the comments to the original posting. You would instead use images from your server connection.
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
import javax.swing.Icon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.SwingConstants;
import javax.swing.SwingWorker;
import javax.swing.UIManager;
public class SwingLabelWithUpdatedImage {
public static void main(String args[]) throws Exception {
final JLabel label = new JLabel("", SwingConstants.CENTER);
final JFrame frame = new JFrame("Client");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(label, BorderLayout.CENTER);
final Dimension preferredSize = new Dimension(200, 100);
frame.setPreferredSize(preferredSize);
frame.setVisible(true);
frame.pack();
final ImageUpdateWorker task = new ImageUpdateWorker(label);
task.execute();
}
public static class ImageUpdateWorker extends SwingWorker<Void, IconInfo> {
// iconInfoList is not need in your code. It's here so I can
// supply a dummy set of icons to demonstrate UI updates.
final List<IconInfo> iconInfoList;
private JLabel label;
ImageUpdateWorker(JLabel label) {
this.label = label;
// Delete this in your code
this.iconInfoList = initIconInfoList();
}
#Override
public Void doInBackground() {
boolean isTrue = true;
while (isTrue) {
// Put your socket code to read the next icon from a server.
// You don't need to do the ImageIO.write(), ImageIO.read() dance,
// unless you must save the icon to disk. In that case, you don't need
// to read it back in.
// Here, I just rotate the iconInfoList to make it
// appear as though a new icon was received.
// Your code will not have any need to do this.
Collections.rotate(iconInfoList, -1);
// Just publish the icon you create from the image
// you receive from your remote server.
publish(iconInfoList.get(0));
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
return null;
}
#Override
protected void process(List<IconInfo> icons) {
// You might check for an empty list.
// #kleopatra's suggestion to get the last icon is correct.
// See https://docs.oracle.com/javase/tutorial/uiswing/concurrency/interim.html
IconInfo iconInfo = icons.get(icons.size() - 1);
label.setIcon(iconInfo.icon);
// Your code will not do this
label.setText(iconInfo.name);
// You can get the icon dimensions just from the icon,
// so you don't really need the IconInfo class.
label.setSize(iconInfo.dimension);
}
/** Demo code only. It doesn't belong in your working code.
*/
protected List<IconInfo> initIconInfoList() {
// Just a quick way to get some icons; don't need to
// fetch from a server just to demonstrate how to
// refresh the UI.
List<IconInfo> iconInfoList = UIManager.getDefaults().keySet().stream()
.filter(this::isIconKey)
.map(IconInfo::new)
.filter(iconInfo -> iconInfo.icon != null)
.collect(Collectors.toList());
return iconInfoList;
}
/** Demo code only. It doesn't belong in your working code.
*/
protected boolean isIconKey(Object key) {
return String.class.isAssignableFrom(key.getClass())
&& ((String) key).toLowerCase().contains("icon");
}
}
/** This is just a convenience to convey
* the icon and its UIManager key (i.e., name).
* Your remote server doesn't supply a name,
* so you don't really need this class.
* It's just to make the demo more expressive.
*/
public static class IconInfo {
final private String name;
final private Icon icon;
final private Dimension dimension;
IconInfo(Object name) {
this.name = name.toString();
icon = UIManager.getIcon(name);
dimension = icon == null
? new Dimension(32, 32)
: new Dimension(icon.getIconWidth(), icon.getIconHeight());
}
}
}

Automatically closing VLC player when video complete?

So I'm using VLCJ and the VLC player for java to play a video when I run my program. Problem is, the video player only closes when the user clicks the "x" button. Is there a way to close it automatically when the video ends?
Thanks!
If it helps, here's my code:
//////Main class:
package switchAndAnim;
import java.io.File;
import javax.swing.JFileChooser;
public class Start {
public static void main(String[] args)
{
//location of vlc files, media file
new MediaPlayer("vlc-2.0.2", "ryankilp2.wmv").run();
}
}
///////MediaPlayer class:
package switchAndAnim;
import javax.swing.JFrame;
import com.sun.jna.NativeLibrary;
import uk.co.caprica.vlcj.component.EmbeddedMediaPlayerComponent;
import uk.co.caprica.vlcj.runtime.RuntimeUtil;
public class MediaPlayer {
private JFrame ourFrame = new JFrame();
private EmbeddedMediaPlayerComponent ourMediaPlayer;
private String mediaPath = "";
MediaPlayer(String vlcPath,String mediaURL)
{
this.mediaPath = mediaURL;
NativeLibrary.addSearchPath(RuntimeUtil.getLibVlcLibraryName(), vlcPath);
ourMediaPlayer = new EmbeddedMediaPlayerComponent();
ourFrame.setContentPane(ourMediaPlayer);
ourFrame.setSize(640,480);
ourFrame.setVisible(true);
ourFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public void run()
{
ourMediaPlayer.getMediaPlayer().playMedia(mediaPath);
}
}
The media player has all sorts of events you can listen for, one of them being the "finished" event that fires when the end of the video is reached.
ourMediaPlayer = new EmbeddedMediaPlayerComponent() {
public void finished(MediaPlayer mediaPlayer) {
ourMediaPlayer.release(); // In practice, this line is optional
System.exit(0);
}
}
I used System.exit() since your question set EXIT_ON_CLOSE, but equally you could hide or dispose the frame instead depending on your use case.

How to implement Full-Screen Exclusive Mode API

I have a big java program made in GUI using netbeans, in which I have many java files. I have used frame.setExtendedState(JFrame.MAXIMIZED_BOTH); but it doesn't work well for me. What I actually want is that the items get re-sized to full screen that's when I came across this API. I want to know how to implement this API into my program. The problem is that I am a newbie (I make most of the program using Netbeans GUI) and I don't know exactly where should I add the code to make it use this API
Is there a easy way to do it? Which does not require me to make the whole program again?
You should go through the Full Exclusive Mode tutorial. All it is is a matter of checking is full screen mode is supported. If it is, then get the screen device and setFullScreenWindow(...). If it's not supported, just use regular windowing.
See this simple example
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
public class FullWindow extends JFrame {
private boolean isFullScreen = false;
private GraphicsDevice device;
public FullWindow(GraphicsDevice device) {
this.device = device;
initFullScreen();
}
private void initFullScreen() {
isFullScreen = device.isFullScreenSupported();
setDefaultCloseOperation(EXIT_ON_CLOSE);
setUndecorated(isFullScreen);
setResizable(!isFullScreen);
if (isFullScreen) {
// Full-screen mode
device.setFullScreenWindow(this);
validate();
} else {
// Windowed mode
this.setExtendedState(MAXIMIZED_BOTH);
this.setVisible(true);
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
GraphicsEnvironment env = GraphicsEnvironment
.getLocalGraphicsEnvironment();
GraphicsDevice device = env.getDefaultScreenDevice();
new FullWindow(device);
}
});
}
}

How do I resize a JScrollPane within a JFrame? And how do I read from a file in Java?

I have a song library, and I would like this selection list to only be on the left hand side of the window because I want to put other information about the song on the righthand side. I'm not sure how to change the size of JScrollPane, which is inside the JFrame.
In this library, I want to be able to import the songs stored in a file to my song library. Right now, I have an array within my code, but I want to be able to read from a text file instead of using this approach. In the file, I want to be able to store artist and album information about the song, but I don't want it to display in the song list.
String songs[] = {"Song1", "Song2", "Song3", "Song4", "Song5"};
JList list = new JList(songs);
public SongLib(){
JFrame songLibrary = new JFrame("Song Library");
songLibrary.setLocationRelativeTo(null);
songLibrary.setResizable(true);
songLibrary.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
list.addListSelectionListener(new ListSelectionListener(){
public void valueChanged(ListSelectionEvent evt){
int i = list.getSelectedIndex();
if (i != -1)
System.out.println("Selected: " + songs[i]);
else
System.out.println("Choose a song");
}
});
JScrollPane JSPane = new JScrollPane(list);
JSPane.setPreferredSize(new Dimension(100,100));
songLibrary.add(JSPane);
songLibrary.setSize(400,400);
songLibrary.setVisible(true);
}
public static void main(String[] args){
new SongLib();
}
Stop calling (for the rest of your entire life) setPreferredSize(). Meaning that this call: JSPane.setPreferredSize(new Dimension(100,100)); should definitely be removed.
If you want to have 2 panels side-by-side with a draggable separator: use JSplitPane. If you don't want the draggable divider, use a JPanel with an appropriate LayoutManager (GridBagLayout may be a good choice)
Reading from a file is pretty easy, just make a search on SO and you will find hundreds of response. If you want to parse csv-files, there are some libraries around that can help you do that. Eventually, if you consider making this an application for a while, there are some small pure-java, embeddable, databases which will do a much better job at reading/storing/searching information than a simple text-file.
Learn the Java naming conventions and stick to them: variables always start with a lower-case letter.
In addition to #Guillaume Polet's good advice, setVisibleRowCount() may be useful to you going forward.
import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.JList;
import javax.swing.JScrollPane;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
/** #see https://stackoverflow.com/a/14801908/230513 */
public class SongLib {
String songs[] = {"Song1", "Song2", "Song3", "Song4", "Song5"};
JList list = new JList(songs);
public SongLib() {
JFrame songLibrary = new JFrame("Song Library");
songLibrary.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
list.setVisibleRowCount(4);
list.addListSelectionListener(new ListSelectionListener() {
#Override
public void valueChanged(ListSelectionEvent evt) {
int i = list.getSelectedIndex();
if (i != -1) {
System.out.println("Selected: " + songs[i]);
} else {
System.out.println("Choose a song");
}
}
});
JScrollPane JSPane = new JScrollPane(list);
songLibrary.add(JSPane);
songLibrary.pack();
songLibrary.setLocationRelativeTo(null);
songLibrary.setVisible(true);
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
new SongLib();
}
});
}
}
For 1., take a look at layouting in Java, especially the GridBagLayout.
http://docs.oracle.com/javase/tutorial/uiswing/layout/gridbag.html
For 2: Reading and writing from / into files is made by using File-Objects and Inout/Output-Streams. But this is a very low level way to do this.
I think you should consider using an XML file. Take a look at JAXB

Capturing image from webcam in java?

How can I continuously capture images from a webcam?
I want to experiment with object recognition (by maybe using java media framework).
I was thinking of creating two threads
one thread:
Node 1: capture live image
Node 2: save image as "1.jpg"
Node 3: wait 5 seconds
Node 4: repeat...
other thread:
Node 1: wait until image is captured
Node 2: using the "1.jpg" get colors
from every pixle
Node 3: save data in arrays
Node 4: repeat...
This JavaCV implementation works fine.
Code:
import org.bytedeco.javacv.*;
import org.bytedeco.opencv.opencv_core.IplImage;
import java.io.File;
import static org.bytedeco.opencv.global.opencv_core.cvFlip;
import static org.bytedeco.opencv.helper.opencv_imgcodecs.cvSaveImage;
public class Test implements Runnable {
final int INTERVAL = 100;///you may use interval
CanvasFrame canvas = new CanvasFrame("Web Cam");
public Test() {
canvas.setDefaultCloseOperation(javax.swing.JFrame.EXIT_ON_CLOSE);
}
public void run() {
new File("images").mkdir();
FrameGrabber grabber = new OpenCVFrameGrabber(0); // 1 for next camera
OpenCVFrameConverter.ToIplImage converter = new OpenCVFrameConverter.ToIplImage();
IplImage img;
int i = 0;
try {
grabber.start();
while (true) {
Frame frame = grabber.grab();
img = converter.convert(frame);
//the grabbed frame will be flipped, re-flip to make it right
cvFlip(img, img, 1);// l-r = 90_degrees_steps_anti_clockwise
//save
cvSaveImage("images" + File.separator + (i++) + "-aa.jpg", img);
canvas.showImage(converter.convert(img));
Thread.sleep(INTERVAL);
}
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
Test gs = new Test();
Thread th = new Thread(gs);
th.start();
}
}
There is also post on configuration for JavaCV
You can modify the code and be able to save the images in regular interval and do rest of the processing you want.
Some time ago I've created generic Java library which can be used to take pictures with a PC webcam. The API is very simple, not overfeatured, can work standalone, but also supports additional webcam drivers like OpenIMAJ, JMF, FMJ, LTI-CIVIL, etc, and some IP cameras.
Link to the project is https://github.com/sarxos/webcam-capture
Example code (take picture and save in test.jpg):
Webcam webcam = Webcam.getDefault();
webcam.open();
BufferedImage image = webcam.getImage();
ImageIO.write(image, "JPG", new File("test.jpg"));
It is also available in Maven Central Repository or as a separate ZIP which includes all required dependencies and 3rd party JARs.
JMyron is very simple for use.
http://webcamxtra.sourceforge.net/
myron = new JMyron();
myron.start(imgw, imgh);
myron.update();
int[] img = myron.image();
Here is a similar question with some - yet unaccepted - answers. One of them mentions FMJ as a java alternative to JMF.
This kind of goes off of gt_ebuddy's answer using JavaCV, but my video output is at a much higher quality then his answer. I've also added some other random improvements (such as closing down the program when ESC and CTRL+C are pressed, and making sure to close down the resources the program uses properly).
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.image.BufferedImage;
import javax.swing.AbstractAction;
import javax.swing.ActionMap;
import javax.swing.InputMap;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.KeyStroke;
import com.googlecode.javacv.CanvasFrame;
import com.googlecode.javacv.OpenCVFrameGrabber;
import com.googlecode.javacv.cpp.opencv_core.IplImage;
public class HighRes extends JComponent implements Runnable {
private static final long serialVersionUID = 1L;
private static CanvasFrame frame = new CanvasFrame("Web Cam");
private static boolean running = false;
private static int frameWidth = 800;
private static int frameHeight = 600;
private static OpenCVFrameGrabber grabber = new OpenCVFrameGrabber(0);
private static BufferedImage bufImg;
public HighRes()
{
// setup key bindings
ActionMap actionMap = frame.getRootPane().getActionMap();
InputMap inputMap = frame.getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
for (Keys direction : Keys.values())
{
actionMap.put(direction.getText(), new KeyBinding(direction.getText()));
inputMap.put(direction.getKeyStroke(), direction.getText());
}
frame.getRootPane().setActionMap(actionMap);
frame.getRootPane().setInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW, inputMap);
// setup window listener for close action
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.addWindowListener(new WindowAdapter()
{
public void windowClosing(WindowEvent e)
{
stop();
}
});
}
public static void main(String... args)
{
HighRes webcam = new HighRes();
webcam.start();
}
#Override
public void run()
{
try
{
grabber.setImageWidth(frameWidth);
grabber.setImageHeight(frameHeight);
grabber.start();
while (running)
{
final IplImage cvimg = grabber.grab();
if (cvimg != null)
{
// cvFlip(cvimg, cvimg, 1); // mirror
// show image on window
bufImg = cvimg.getBufferedImage();
frame.showImage(bufImg);
}
}
grabber.stop();
grabber.release();
frame.dispose();
}
catch (Exception e)
{
e.printStackTrace();
}
}
public void start()
{
new Thread(this).start();
running = true;
}
public void stop()
{
running = false;
}
private class KeyBinding extends AbstractAction {
private static final long serialVersionUID = 1L;
public KeyBinding(String text)
{
super(text);
putValue(ACTION_COMMAND_KEY, text);
}
#Override
public void actionPerformed(ActionEvent e)
{
String action = e.getActionCommand();
if (action.equals(Keys.ESCAPE.toString()) || action.equals(Keys.CTRLC.toString())) stop();
else System.out.println("Key Binding: " + action);
}
}
}
enum Keys
{
ESCAPE("Escape", KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0)),
CTRLC("Control-C", KeyStroke.getKeyStroke(KeyEvent.VK_C, KeyEvent.CTRL_DOWN_MASK)),
UP("Up", KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0)),
DOWN("Down", KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0)),
LEFT("Left", KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, 0)),
RIGHT("Right", KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, 0));
private String text;
private KeyStroke keyStroke;
Keys(String text, KeyStroke keyStroke)
{
this.text = text;
this.keyStroke = keyStroke;
}
public String getText()
{
return text;
}
public KeyStroke getKeyStroke()
{
return keyStroke;
}
#Override
public String toString()
{
return text;
}
}
You can try Java Webcam SDK library also.
SDK demo applet is available at link.
I have used JMF on a videoconference application and it worked well on two laptops: one with integrated webcam and another with an old USB webcam. It requires JMF being installed and configured before-hand, but once you're done you can access the hardware via Java code fairly easily.
You can try Marvin Framework. It provides an interface to work with cameras. Moreover, it also provides a set of real-time video processing features, like object tracking and filtering.
Take a look!
Real-time Video Processing Demo:
http://www.youtube.com/watch?v=D5mBt0kRYvk
You can use the source below. Just save a frame using MarvinImageIO.saveImage() every 5 second.
Webcam video demo:
public class SimpleVideoTest extends JFrame implements Runnable{
private MarvinVideoInterface videoAdapter;
private MarvinImage image;
private MarvinImagePanel videoPanel;
public SimpleVideoTest(){
super("Simple Video Test");
videoAdapter = new MarvinJavaCVAdapter();
videoAdapter.connect(0);
videoPanel = new MarvinImagePanel();
add(videoPanel);
new Thread(this).start();
setSize(800,600);
setVisible(true);
}
#Override
public void run() {
while(true){
// Request a video frame and set into the VideoPanel
image = videoAdapter.getFrame();
videoPanel.setImage(image);
}
}
public static void main(String[] args) {
SimpleVideoTest t = new SimpleVideoTest();
t.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
For those who just want to take a single picture:
WebcamPicture.java
public class WebcamPicture {
public static void main(String[] args) {
try{
MarvinVideoInterface videoAdapter = new MarvinJavaCVAdapter();
videoAdapter.connect(0);
MarvinImage image = videoAdapter.getFrame();
MarvinImageIO.saveImage(image, "./res/webcam_picture.jpg");
} catch(MarvinVideoInterfaceException e){
e.printStackTrace();
}
}
}
I used Webcam Capture API. You can download it from here
webcam = Webcam.getDefault();
webcam.open();
if (webcam.isOpen()) { //if web cam open
BufferedImage image = webcam.getImage();
JLabel imageLbl = new JLabel();
imageLbl.setSize(640, 480); //show captured image
imageLbl.setIcon(new ImageIcon(image));
int showConfirmDialog = JOptionPane.showConfirmDialog(null, imageLbl, "Image Viewer", JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE, new ImageIcon(""));
if (showConfirmDialog == JOptionPane.YES_OPTION) {
JFileChooser chooser = new JFileChooser();
chooser.setDialogTitle("Save Image");
chooser.setFileFilter(new FileNameExtensionFilter("IMAGES ONLY", "png", "jpeg", "jpg")); //this file extentions are shown
int showSaveDialog = chooser.showSaveDialog(this);
if (showSaveDialog == 0) { //if pressed 'Save' button
String filePath = chooser.getCurrentDirectory().toString().replace("\\", "/");
String fileName = chooser.getSelectedFile().getName(); //get user entered file name to save
ImageIO.write(image, "PNG", new File(filePath + "/" + fileName + ".png"));
}
}
}
http://grack.com/downloads/school/enel619.10/report/java_media_framework.html
Using the Player with Swing
The Player can be easily used in a Swing application as well. The following code creates a Swing-based TV capture program with the video output displayed in the entire window:
import javax.media.*;
import javax.swing.*;
import java.awt.*;
import java.net.*;
import java.awt.event.*;
import javax.swing.event.*;
public class JMFTest extends JFrame {
Player _player;
JMFTest() {
addWindowListener( new WindowAdapter() {
public void windowClosing( WindowEvent e ) {
_player.stop();
_player.deallocate();
_player.close();
System.exit( 0 );
}
});
setExtent( 0, 0, 320, 260 );
JPanel panel = (JPanel)getContentPane();
panel.setLayout( new BorderLayout() );
String mediaFile = "vfw://1";
try {
MediaLocator mlr = new MediaLocator( mediaFile );
_player = Manager.createRealizedPlayer( mlr );
if (_player.getVisualComponent() != null)
panel.add("Center", _player.getVisualComponent());
if (_player.getControlPanelComponent() != null)
panel.add("South", _player.getControlPanelComponent());
}
catch (Exception e) {
System.err.println( "Got exception " + e );
}
}
public static void main(String[] args) {
JMFTest jmfTest = new JMFTest();
jmfTest.show();
}
}
Java usually doesn't like accessing hardware, so you will need a driver program of some sort, as goldenmean said. I've done this on my laptop by finding a command line program that snaps a picture. Then it's the same as goldenmean explained; you run the command line program from your java program in the takepicture() routine, and the rest of your code runs the same.
Except for the part about reading pixel values into an array, you might be better served by saving the file to BMP, which is nearly that format already, then using the standard java image libraries on it.
Using a command line program adds a dependency to your program and makes it less portable, but so was the webcam, right?
I believe the web-cam application software which comes along with the web-cam, or you native windows webcam software can be run in a batch script(windows/dos script) after turning the web cam on(i.e. if it needs an external power supply). In the bacth script , u can add appropriate delay to capture after certain time period. And keep executing the capture command in loop.
I guess this should be possible
-AD
There's a pretty nice interface for this in processing, which is kind of a pidgin java designed for graphics. It gets used in some image recognition work, such as that link.
Depending on what you need out of it, you might be able to load the video library that's used there in java, or if you're just playing around with it you might be able to get by using processing itself.
FMJ can do this, as can the supporting library it uses, LTI-CIVIL. Both are on sourceforge.
Recommand using FMJ for multimedia relatived java app.
Try using JMyron How To Use Webcam Using Java. I think using JMyron is the easiest way to access a webcam using java. I tried to use it with a 64-bit processor, but it gave me an error. It worked just fine on a 32-bit processor, though.

Categories