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}