001package com.github.sarxos.webcam.ds.openimaj; 002 003import java.awt.Dimension; 004import java.awt.image.BufferedImage; 005 006import org.openimaj.image.ImageUtilities; 007import org.openimaj.video.capture.Device; 008import org.openimaj.video.capture.VideoCapture; 009import org.openimaj.video.capture.VideoCaptureException; 010import org.slf4j.Logger; 011import org.slf4j.LoggerFactory; 012 013import com.github.sarxos.webcam.WebcamDevice; 014import com.github.sarxos.webcam.WebcamException; 015 016 017public class OpenImajDevice implements WebcamDevice { 018 019 private static final Logger LOG = LoggerFactory.getLogger(OpenImajDriver.class); 020 021 /** 022 * Artificial view sizes. I'm really not sure if will fit into other webcams 023 * but hope that OpenIMAJ can handle this. 024 */ 025 private final static Dimension[] DIMENSIONS = new Dimension[] { 026 new Dimension(176, 144), 027 new Dimension(320, 240), 028 new Dimension(352, 288), 029 new Dimension(640, 400), 030 new Dimension(640, 480), 031 new Dimension(1280, 720), 032 }; 033 034 private Device device = null; 035 private VideoCapture capture = null; 036 private Dimension size = null; 037 038 private volatile boolean open = false; 039 private volatile boolean disposed = false; 040 041 public OpenImajDevice(Device device) { 042 this.device = device; 043 } 044 045 @Override 046 public String getName() { 047 return device.getNameStr(); 048 } 049 050 @Override 051 public Dimension[] getResolutions() { 052 return DIMENSIONS; 053 } 054 055 @Override 056 public Dimension getResolution() { 057 return size; 058 } 059 060 @Override 061 public void setResolution(Dimension size) { 062 if (open) { 063 throw new RuntimeException("Cannot set new size when device is open, please close it first"); 064 } 065 this.size = size; 066 } 067 068 @Override 069 public BufferedImage getImage() { 070 071 if (!open) { 072 throw new RuntimeException("Cannot get image from closed device"); 073 } 074 075 // TODO scale to dimension if not equal 076 return ImageUtilities.createBufferedImageForDisplay(capture.getNextFrame()); 077 } 078 079 @Override 080 public void open() { 081 082 if (disposed) { 083 LOG.warn("Cannot open device because it's already disposed"); 084 return; 085 } 086 087 if (open) { 088 return; 089 } 090 091 try { 092 capture = new VideoCapture(size.width, size.height, device); 093 } catch (VideoCaptureException e) { 094 throw new WebcamException("Cannot initialize video capture", e); 095 } 096 open = true; 097 098 // what the hell is that something below? that's ugly w/a for black 099 // images at the very capture beginning, if you have some other idea of 100 // how to remove them, please share or fix 101 102 int i = 0; 103 do { 104 capture.getNextFrame(); 105 try { 106 Thread.sleep(1000); 107 } catch (InterruptedException e) { 108 } 109 } while (i++ < 3); 110 111 LOG.info("OpenIMAJ webcam device has been initialized"); 112 } 113 114 @Override 115 public void close() { 116 117 if (!open) { 118 return; 119 } 120 121 capture.stopCapture(); 122 123 open = false; 124 125 LOG.info("OpenIMAJ webcam device has been closed"); 126 } 127 128 @Override 129 public void dispose() { 130 disposed = true; 131 } 132 133 @Override 134 public boolean isOpen() { 135 return open; 136 } 137}