WebcamGrabber.java

package ac.essex.ooechs.imaging.commons.apps.webcam; 
 
import ac.essex.ooechs.imaging.commons.PixelLoader; 
 
import javax.media.*; 
import javax.media.util.BufferToImage; 
import javax.media.control.FrameGrabbingControl; 
import javax.media.control.FormatControl; 
import javax.media.format.VideoFormat; 
import javax.swing.*; 
import java.awt.*; 
import java.awt.event.WindowAdapter; 
import java.awt.event.WindowEvent; 
import java.awt.image.BufferedImage; 
import java.util.Vector; 
import java.util.Collections; 
 
public class WebcamGrabber { 
 
    public JFrame window; 
    private Player player; 
    private Component visualComponent; 
 
    public static void main(String[] args) throws Exception { 
        new WebcamGrabber(); 
    } 
 
    public WebcamGrabber() throws Exception { 
        this(true); 
    } 
 
    public WebcamGrabber(boolean display) throws Exception { 
        try { 
 
            //gets a list of devices how support the given videoformat 
            MyCaptureDeviceInfo[] cams = autoDetect(); 
 
            if (cams.length == 0) { 
                throw new Exception("No webcams detected - did you run jmfinit?"); 
            } 
 
            Object selected = JOptionPane.showInputDialog(null, 
                    "Select Video format", 
                    "Capture format selection", 
                    JOptionPane.INFORMATION_MESSAGE, 
                    null,        //  Icon icon, 
                    cams, // videoFormats, 
                    cams[0]); 
 
            CaptureDeviceInfo device; 
 
            if (selected != null) { 
                device = ((MyCaptureDeviceInfo) selected).capDevInfo; 
            } else { 
                return; 
            } 
 
            MediaLocator ml = device.getLocator(); 
 
            player = Manager.createRealizedPlayer(ml); 
 
            player.start(); 
 
            FormatControl formatControl = (FormatControl) player.getControl("javax.media.control.FormatControl"); 
            Format[] videoFormats = device.getFormats(); 
 
            MyVideoFormat[] myFormatList = new MyVideoFormat[videoFormats.length]; 
            for (int i = 0; i < videoFormats.length; i++) { 
                myFormatList[i] = new MyVideoFormat((VideoFormat) videoFormats[i]); 
            } 
 
            Format currFormat = formatControl.getFormat(); 
 
            visualComponent = player.getVisualComponent(); 
 
            if (visualComponent != null) { 
 
                if (display) { 
 
                    window = new JFrame("Camera"); 
                    window.add(visualComponent); 
                    window.setSize(320, 240); 
                    window.setVisible(true); 
 
                    window.addWindowListener(new WindowAdapter() { 
                        public void windowClosing(WindowEvent e) { 
                            player.stop(); 
                            window.dispose(); 
                        } 
                    }); 
 
                } 
 
                if (currFormat instanceof VideoFormat) { 
                    VideoFormat currentFormat = (VideoFormat) currFormat; 
                    Dimension imageSize = currentFormat.getSize(); 
                    if (display) window.setPreferredSize(imageSize); 
                    else visualComponent.setPreferredSize(imageSize); 
                } else { 
                    System.err.println("Error : Cannot get current video format"); 
                } 
 
            } 
 
        } catch (Exception e) { 
            System.out.println(e); 
        } 
    } 
 
    public Component getVisualComponent() { 
        return visualComponent; 
    } 
 
    public PixelLoader grab() { 
        long start = System.currentTimeMillis(); 
        BufferedImage image = toBufferedImage(grabFrameImage()); 
        PixelLoader p = new PixelLoader(image); 
        return p; 
    } 
 
    private Buffer grabFrameBuffer() { 
        if (player != null) { 
            FrameGrabbingControl fgc = (FrameGrabbingControl) player.getControl("javax.media.control.FrameGrabbingControl"); 
            if (fgc != null) { 
                return (fgc.grabFrame()); 
            } else { 
                System.err.println("Error : FrameGrabbingControl is null"); 
                return (null); 
            } 
        } else { 
            System.err.println("Error : Player is null"); 
            return (null); 
        } 
    } 
 
    private Image grabFrameImage() { 
        Buffer buffer = grabFrameBuffer(); 
        if (buffer != null) { 
            // Convert it to an image 
            BufferToImage btoi = new BufferToImage((VideoFormat) buffer.getFormat()); 
            if (btoi != null) { 
                Image image = btoi.createImage(buffer); 
                if (image != null) { 
                    return (image); 
                } else { 
                    System.err.println("Error : BufferToImage cannot convert buffer"); 
                    return (null); 
                } 
            } else { 
                System.err.println("Error : cannot create BufferToImage instance"); 
                return (null); 
            } 
        } else { 
            System.out.println("Error : Buffer grabbed is null"); 
            return (null); 
        } 
    } 
 
    private BufferedImage toBufferedImage(Image image) { 
        if (image instanceof BufferedImage) { 
            return (BufferedImage)image; 
        } 
 
        // This code ensures that all the pixels in the image are loaded 
        image = new ImageIcon(image).getImage(); 
 
        // Determine if the image has transparent pixels; for this method's 
        // implementation, see e661 Determining If an Image Has Transparent Pixels 
        boolean hasAlpha = false; 
 
        // Create a buffered image with a format that's compatible with the screen 
        BufferedImage bimage = null; 
        GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment(); 
        try { 
            // Determine the type of transparency of the new buffered image 
            int transparency = Transparency.OPAQUE; 
            if (hasAlpha) { 
                transparency = Transparency.BITMASK; 
            } 
 
            // Create the buffered image 
            GraphicsDevice gs = ge.getDefaultScreenDevice(); 
            GraphicsConfiguration gc = gs.getDefaultConfiguration(); 
            bimage = gc.createCompatibleImage( 
                image.getWidth(null), image.getHeight(null), transparency); 
        } catch (HeadlessException e) { 
            // The system does not have a screen 
        } 
 
        if (bimage == null) { 
            // Create a buffered image using the default color model 
            int type = BufferedImage.TYPE_INT_RGB; 
            if (hasAlpha) { 
                type = BufferedImage.TYPE_INT_ARGB; 
            } 
            bimage = new BufferedImage(image.getWidth(null), image.getHeight(null), type); 
        } 
 
        // Copy image to buffered image 
        Graphics g = bimage.createGraphics(); 
 
        // Paint the image onto the buffered image 
        g.drawImage(image, 0, 0, null); 
        g.dispose(); 
 
        return bimage; 
    } 
 
    class MyCaptureDeviceInfo implements Comparable { 
        public CaptureDeviceInfo capDevInfo; 
 
        public MyCaptureDeviceInfo(CaptureDeviceInfo devInfo) { 
            capDevInfo = devInfo; 
        } 
 
        public int compareTo(Object o) { 
            MyCaptureDeviceInfo other = (MyCaptureDeviceInfo) o; 
            boolean thisV = this.capDevInfo.getName().startsWith("v"); 
            boolean otherV = other.capDevInfo.getName().startsWith("v"); 
            if (thisV && !otherV) return -1; 
            if (!thisV && otherV) return +1; 
            return 0;                
        } 
 
        public String toString() { 
            return (capDevInfo.getName()); 
        } 
    } 
 
    public MyCaptureDeviceInfo[] autoDetect() { 
        Vector list = CaptureDeviceManager.getDeviceList(null); 
 
        CaptureDeviceInfo devInfo = null; 
        String name; 
        Vector capDevices = new Vector(); 
 
        if (list != null) { 
 
            for (int i = 0; i < list.size(); i++) { 
                devInfo = (CaptureDeviceInfo) list.elementAt(i); 
                name = devInfo.getName(); 
 
                //if (name.startsWith("vf")) { 
                    System.out.println("DeviceManager List : " + name); 
                    capDevices.addElement(new MyCaptureDeviceInfo(devInfo)); 
                //} 
                System.out.println(name); 
            } 
        } 
 
        Collections.sort(capDevices); 
 
        MyCaptureDeviceInfo[] detected = new MyCaptureDeviceInfo[capDevices.size()]; 
        for (int i = 0; i < capDevices.size(); i++) { 
            detected[i] = (MyCaptureDeviceInfo) capDevices.elementAt(i); 
        } 
 
        return (detected); 
    } 
 
}