Sunday, February 19, 2012

Capturing webcam image with Java Media Framework

I have used Java Media Framework (JMF) quite a lot in the past, and recently I strarted to experiment again with some of my old algorithms. Having changed my computers during these years, I noticed that the old code did not work correctly. Especially, setting the webcam video capture format did not respond. This is the problem I noticed many people were still having, based on the question on the stackoverflow etc.

After some hours of debugging, I found out that the format needs to be set before the javax.media.Player is started. After the player has been started, the FormatControl.setFormat() has no effect.

Here is also a full source code minimal webcam image grabber. Please, let me know if you have problems with it. Please note that the initialization of the video capture device may take some seconds. If you are grabbing images as fast as possible, the first image captures will fail (the images returned have dimension 1x1) until the video capture device is ready.

Use class like this:

    FrameGrabber grabber = new FrameGrabber();
    if (grabber.init()==true) {
        BufferedImage frame = grabber.grab();
    }

And the class source code:
import java.util.Vector;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.image.BufferedImage;
import javax.media.*;
import javax.media.control.FormatControl;
import javax.media.control.FrameGrabbingControl;
import javax.media.format.VideoFormat;
import javax.media.format.YUVFormat;
import javax.media.util.BufferToImage;

//
// source code by tejopa / popscan.blogspot.com, 2012
//

public class FrameGrabber {
 
    CaptureDeviceInfo    _cdi;
    Player               _player;
    FrameGrabbingControl _frameGrabber;
    FormatControl        _formatControl;

    public FrameGrabber() { }
  
    public boolean init() {
     Vector devices = CaptureDeviceManager.getDeviceList(new YUVFormat());
     if (devices.size()<1) {
      System.out.println("No capture devices available!");
     } else {
      _cdi = (CaptureDeviceInfo)devices.elementAt(0);
     }
     try {
            _player = Manager.createRealizedPlayer(_cdi.getLocator());
         _frameGrabber = (FrameGrabbingControl)_player.getControl("javax.media.control.FrameGrabbingControl");
         _formatControl = (FormatControl)_player.getControl("javax.media.control.FormatControl");
         _formatControl.setFormat(_cdi.getFormats()[0]);
         _player.start();
         return true;
     } catch (Exception e) {
      e.printStackTrace();
  }
     return false;
    }
    
    public BufferedImage grab() {
        if (_frameGrabber==null) {
            System.out.println("FrameGrabber is not initialized!");
            return null;
        }
     // Grab a frame from the capture device
        Buffer buf = _frameGrabber.grabFrame();
        // check that buf actually exists!
        if (buf!=null) {
            Image img = new BufferToImage((VideoFormat)buf.getFormat()).createImage(buf);
            // image creation may also fail!
            if (img!=null) {
         BufferedImage bi = new BufferedImage(img.getWidth(null), img.getHeight(null), BufferedImage.TYPE_INT_ARGB);
  Graphics2D g = bi.createGraphics();
  g.drawImage(img, 0,0, null);
  return bi;
            }
        } 
        // grab failed, still return image, but make it empty and small
        BufferedImage bi = new BufferedImage(1,1, BufferedImage.TYPE_INT_ARGB);
        return bi;
    }
}

14 comments:

Jussi said...

I noticed that many are reading this post, but no one has left any comments... Does the code work in your setups?!

Anonymous said...

Hello! thanks for the Codes.

Please i got this error when i debugged it . any clue pls?

java.lang.NoSuchMethodError: main
Exception in thread "main" Java Result: 1
BUILD SUCCESSFUL (total time: 1 second)

thanks

Jussi said...

Hi and thanks for the feedback!

Check that you are using the last release for Java Media Framework (JMF): http://www.oracle.com/technetwork/java/javase/download-142937.html

If you do not know what JMF is, check this page: http://www.oracle.com/technetwork/java/javase/tech/index-jsp-140239.html

Anonymous said...

no capture device available...what is this

Jussi said...

Hi! It seems that you don't have webcam or other capture device present which Java Media Framework recognizes. Use setup/install feature in JMF which iterates through your devices and makes them available for Java.

Rehman said...

I am trying do run your code on laptop. Which contain camera but your replying tha no capturing device available. Now what extra i have to do. Any comment

Jussi said...

Hi! You have to install Java Media Framework (JMF) which is sadly no longer developed... It might require tricks to get the JMF installed, but after installation, you should run the capture devices detection from JMF. For example for me the JMF utilities are in C:\JMF2.1.1e\bin\

Try to run jmfinit.exe and the others exes available. They should be able to find your capture devices if they can be used with JMF.

NANBAN said...

Sorry its not work...
I do your instructions everything....
I get this error only...
"No capture devices available!
java.lang.NullPointerException
at Capture.init(Capture.java:33)
at Capture.main(Capture.java:69)
"

Jussi said...

Maybe the JMF was not properly configured? Have you tried to use the utilities from the JMF package, like JMFRegistry.exe? The application will check the devices that can be used with the JMF.

vignesh raja said...

Can you please elaborate the working of the code?

vignesh raja said...

I tried your program i too get an error saying that "No capture devices available!"
Pls help me soon

Jussi said...

Please, make sure that you have installed Java Media Framework (JMF) package correctly. As the JMF is old, it is 32-bit version. Your Java SDK must be also 32-bit version.

Akshay Gaykar said...

please try to run code from command prompt. your problem will get easily solved cause for other IDE path for jmf is not avilable.
or
try to set path for jmf and then try






Anonymous said...

Hi

i have just tried your code
Thanks for it.

What have it to perform ?
The code work properly but my webcam stay started and no thing happen.