diff --git a/webcam-capture-drivers/webcam-capture-driver-ipcam/.classpath b/webcam-capture-drivers/webcam-capture-driver-ipcam/.classpath
index e147e777..7690b17d 100644
--- a/webcam-capture-drivers/webcam-capture-driver-ipcam/.classpath
+++ b/webcam-capture-drivers/webcam-capture-driver-ipcam/.classpath
@@ -1,32 +1,11 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
-
-
-
-
-
-
-
-
-
-
+
+
+
diff --git a/webcam-capture-drivers/webcam-capture-driver-ipcam/pom.xml b/webcam-capture-drivers/webcam-capture-driver-ipcam/pom.xml
index 01b2e58e..5a288eb8 100644
--- a/webcam-capture-drivers/webcam-capture-driver-ipcam/pom.xml
+++ b/webcam-capture-drivers/webcam-capture-driver-ipcam/pom.xml
@@ -77,12 +77,17 @@
org.apache.httpcomponents
httpclient
- 4.2.2
+ 4.2.3
org.apache.httpcomponents
httpmime
- 4.2.2
+ 4.2.3
+
+
+ ch.qos.logback
+ logback-classic
+ 1.0.9
diff --git a/webcam-capture-drivers/webcam-capture-driver-ipcam/src/examples/java/com/github/sarxos/webcam/ds/ipcam/JpegExample.java b/webcam-capture-drivers/webcam-capture-driver-ipcam/src/examples/java/com/github/sarxos/webcam/ds/ipcam/JpegExample.java
index a7689708..ea160ac7 100644
--- a/webcam-capture-drivers/webcam-capture-driver-ipcam/src/examples/java/com/github/sarxos/webcam/ds/ipcam/JpegExample.java
+++ b/webcam-capture-drivers/webcam-capture-driver-ipcam/src/examples/java/com/github/sarxos/webcam/ds/ipcam/JpegExample.java
@@ -1,8 +1,12 @@
package com.github.sarxos.webcam.ds.ipcam;
+import java.awt.Dimension;
+import java.awt.GridLayout;
import java.net.MalformedURLException;
-import java.net.URL;
+import java.util.ArrayList;
+import java.util.List;
+import javax.swing.BorderFactory;
import javax.swing.JFrame;
import com.github.sarxos.webcam.Webcam;
@@ -17,23 +21,28 @@ public static void main(String[] args) throws MalformedURLException {
// available to be viewed online. Here in this example we are creating
// IP camera device working in PULL mode to request static JPEG images.
- String address = "http://www.dasding.de/ext/webcam/webcam770.php?cam=1";
- IpCamDevice livecam = new IpCamDevice("dasding", new URL(address), IpCamMode.PULL);
+ JFrame f = new JFrame("Dasding Studio Live IP Cameras");
+ f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+ f.setLayout(new GridLayout(0, 3, 1, 1));
+
+ List panels = new ArrayList();
- IpCamDriver driver = new IpCamDriver();
- driver.register(livecam);
+ for (Webcam webcam : Webcam.getWebcams()) {
- Webcam.setDriver(driver);
+ WebcamPanel panel = new WebcamPanel(webcam, new Dimension(256, 144), false);
+ panel.setFillArea(true);
+ panel.setFPS(0.2); // 0.2 FPS = 1 frame per 5 seconds
+ panel.setBorder(BorderFactory.createEmptyBorder());
- WebcamPanel panel = new WebcamPanel(Webcam.getDefault());
- panel.setFPS(0.2); // 1 frame per 5 seconds
+ f.add(panel);
+ panels.add(panel);
+ }
- JFrame f = new JFrame("Dasding Studio Live IP Camera");
- f.add(panel);
f.pack();
f.setVisible(true);
- f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+ for (WebcamPanel panel : panels) {
+ panel.start();
+ }
}
-
}
diff --git a/webcam-capture-drivers/webcam-capture-driver-ipcam/src/examples/resources/cameras.xml b/webcam-capture-drivers/webcam-capture-driver-ipcam/src/examples/resources/cameras.xml
new file mode 100644
index 00000000..46258ec0
--- /dev/null
+++ b/webcam-capture-drivers/webcam-capture-driver-ipcam/src/examples/resources/cameras.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
diff --git a/webcam-capture-drivers/webcam-capture-driver-ipcam/src/main/java/com/github/sarxos/webcam/ds/ipcam/IpCamDevice.java b/webcam-capture-drivers/webcam-capture-driver-ipcam/src/main/java/com/github/sarxos/webcam/ds/ipcam/IpCamDevice.java
index ba8b96ba..6000d172 100644
--- a/webcam-capture-drivers/webcam-capture-driver-ipcam/src/main/java/com/github/sarxos/webcam/ds/ipcam/IpCamDevice.java
+++ b/webcam-capture-drivers/webcam-capture-driver-ipcam/src/main/java/com/github/sarxos/webcam/ds/ipcam/IpCamDevice.java
@@ -245,14 +245,21 @@ public Dimension[] getSizes() {
open();
}
- BufferedImage img = getImage();
- int w = img.getWidth();
- int h = img.getHeight();
-
- sizes = new Dimension[] { new Dimension(w, h) };
+ int attempts = 0;
+ do {
+ BufferedImage img = getImage();
+ if (img != null) {
+ sizes = new Dimension[] { new Dimension(img.getWidth(), img.getHeight()) };
+ break;
+ }
+ } while (attempts++ < 5);
close();
+ if (sizes == null) {
+ throw new WebcamException("Cannot get initial image from IP camera device " + getName());
+ }
+
return sizes;
}
diff --git a/webcam-capture-drivers/webcam-capture-driver-ipcam/src/main/java/com/github/sarxos/webcam/ds/ipcam/IpCamDeviceRegistry.java b/webcam-capture-drivers/webcam-capture-driver-ipcam/src/main/java/com/github/sarxos/webcam/ds/ipcam/IpCamDeviceRegistry.java
index 344c9674..248028c6 100644
--- a/webcam-capture-drivers/webcam-capture-driver-ipcam/src/main/java/com/github/sarxos/webcam/ds/ipcam/IpCamDeviceRegistry.java
+++ b/webcam-capture-drivers/webcam-capture-driver-ipcam/src/main/java/com/github/sarxos/webcam/ds/ipcam/IpCamDeviceRegistry.java
@@ -2,9 +2,8 @@
import java.net.URL;
import java.util.ArrayList;
-import java.util.HashSet;
+import java.util.Collections;
import java.util.List;
-import java.util.Set;
import com.github.sarxos.webcam.WebcamDevice;
import com.github.sarxos.webcam.WebcamException;
@@ -20,7 +19,7 @@ public class IpCamDeviceRegistry {
/**
* Contains IP cameras.
*/
- private static final Set DEVICES = new HashSet();
+ private static final List DEVICES = new ArrayList();
/**
* Register IP camera.
@@ -41,6 +40,10 @@ public static void register(String name, URL url, IpCamMode mode) {
register(new IpCamDevice(name, url, mode));
}
+ public static void register(String name, URL url, IpCamMode mode, IpCamAuth auth) {
+ register(new IpCamDevice(name, url, mode, auth));
+ }
+
public static boolean isRegistered(IpCamDevice ipcam) {
for (IpCamDevice d : DEVICES) {
if (d.getName().equals(ipcam.getName())) {
@@ -83,6 +86,6 @@ public static void unregister(IpCamDevice ipcam) {
* @return Collection of registered IP cameras
*/
public static List getIpCameras() {
- return new ArrayList(DEVICES);
+ return Collections.unmodifiableList(DEVICES);
}
}
diff --git a/webcam-capture-drivers/webcam-capture-driver-ipcam/src/main/java/com/github/sarxos/webcam/ds/ipcam/IpCamDriver.java b/webcam-capture-drivers/webcam-capture-driver-ipcam/src/main/java/com/github/sarxos/webcam/ds/ipcam/IpCamDriver.java
index 7e438419..8ca04452 100644
--- a/webcam-capture-drivers/webcam-capture-driver-ipcam/src/main/java/com/github/sarxos/webcam/ds/ipcam/IpCamDriver.java
+++ b/webcam-capture-drivers/webcam-capture-driver-ipcam/src/main/java/com/github/sarxos/webcam/ds/ipcam/IpCamDriver.java
@@ -14,6 +14,16 @@
*/
public class IpCamDriver implements WebcamDriver {
+ public IpCamDriver() {
+ this(null);
+ }
+
+ public IpCamDriver(IpCamStorage storage) {
+ if (storage != null) {
+ storage.open();
+ }
+ }
+
@Override
public List getDevices() {
return Collections.unmodifiableList((List extends WebcamDevice>) IpCamDeviceRegistry.getIpCameras());
diff --git a/webcam-capture-drivers/webcam-capture-driver-ipcam/src/main/java/com/github/sarxos/webcam/ds/ipcam/IpCamMode.java b/webcam-capture-drivers/webcam-capture-driver-ipcam/src/main/java/com/github/sarxos/webcam/ds/ipcam/IpCamMode.java
index 101eb428..bbd4a9c2 100644
--- a/webcam-capture-drivers/webcam-capture-driver-ipcam/src/main/java/com/github/sarxos/webcam/ds/ipcam/IpCamMode.java
+++ b/webcam-capture-drivers/webcam-capture-driver-ipcam/src/main/java/com/github/sarxos/webcam/ds/ipcam/IpCamMode.java
@@ -1,20 +1,27 @@
package com.github.sarxos.webcam.ds.ipcam;
+import javax.xml.bind.annotation.XmlEnum;
+import javax.xml.bind.annotation.XmlEnumValue;
+
+
/**
* How to obtain new images from IP cameras.
*
* @author Bartosz Firyn (SarXos)
*/
+@XmlEnum
public enum IpCamMode {
/**
* Device will pull image from IP camera.
*/
+ @XmlEnumValue("pull")
PULL,
/**
* IP camera HTTP server will push new image to the device.
*/
+ @XmlEnumValue("pull")
PUSH,
}
diff --git a/webcam-capture-drivers/webcam-capture-driver-ipcam/src/main/java/com/github/sarxos/webcam/ds/ipcam/IpCamStorage.java b/webcam-capture-drivers/webcam-capture-driver-ipcam/src/main/java/com/github/sarxos/webcam/ds/ipcam/IpCamStorage.java
new file mode 100644
index 00000000..838b96e7
--- /dev/null
+++ b/webcam-capture-drivers/webcam-capture-driver-ipcam/src/main/java/com/github/sarxos/webcam/ds/ipcam/IpCamStorage.java
@@ -0,0 +1,73 @@
+package com.github.sarxos.webcam.ds.ipcam;
+
+import java.io.File;
+import java.util.List;
+
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.JAXBException;
+import javax.xml.bind.Unmarshaller;
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+
+import com.github.sarxos.webcam.WebcamException;
+import com.github.sarxos.webcam.ds.ipcam.impl.IpCamDescriptor;
+
+
+@XmlRootElement(name = "storage")
+@XmlAccessorType(XmlAccessType.FIELD)
+public class IpCamStorage {
+
+ private static final Class>[] CLASSES = new Class>[] {
+ IpCamStorage.class,
+ IpCamDescriptor.class,
+ };
+
+ private static final JAXBContext CTX;
+ static {
+ JAXBContext c = null;
+ try {
+ c = JAXBContext.newInstance(CLASSES);
+ } catch (JAXBException e) {
+ throw new RuntimeException(e);
+ } finally {
+ CTX = c;
+ }
+ }
+
+ @XmlElement(name = "ipcam")
+ private List descriptors = null;
+
+ private transient File file = null;
+
+ protected IpCamStorage() {
+ }
+
+ public IpCamStorage(String file) {
+ this(new File(file));
+ }
+
+ public IpCamStorage(File file) {
+ this.file = file;
+ }
+
+ protected List getDescriptors() {
+ return descriptors;
+ }
+
+ public void open() {
+
+ IpCamStorage storage = null;
+ try {
+ Unmarshaller unmarshaller = CTX.createUnmarshaller();
+ storage = (IpCamStorage) unmarshaller.unmarshal(file);
+ } catch (JAXBException e) {
+ throw new WebcamException(e);
+ }
+
+ for (IpCamDescriptor d : storage.getDescriptors()) {
+ IpCamDeviceRegistry.register(d.getName(), d.getURL(), d.getMode(), d.getAuth());
+ }
+ }
+}
diff --git a/webcam-capture-drivers/webcam-capture-driver-ipcam/src/main/java/com/github/sarxos/webcam/ds/ipcam/impl/IpCamDescriptor.java b/webcam-capture-drivers/webcam-capture-driver-ipcam/src/main/java/com/github/sarxos/webcam/ds/ipcam/impl/IpCamDescriptor.java
new file mode 100644
index 00000000..442535a7
--- /dev/null
+++ b/webcam-capture-drivers/webcam-capture-driver-ipcam/src/main/java/com/github/sarxos/webcam/ds/ipcam/impl/IpCamDescriptor.java
@@ -0,0 +1,78 @@
+package com.github.sarxos.webcam.ds.ipcam.impl;
+
+import java.net.MalformedURLException;
+import java.net.URL;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlAttribute;
+import javax.xml.bind.annotation.XmlElement;
+
+import com.github.sarxos.webcam.WebcamException;
+import com.github.sarxos.webcam.ds.ipcam.IpCamAuth;
+import com.github.sarxos.webcam.ds.ipcam.IpCamMode;
+
+
+@XmlAccessorType(XmlAccessType.FIELD)
+public class IpCamDescriptor {
+
+ @XmlAccessorType(XmlAccessType.FIELD)
+ protected static class AuthParams {
+
+ @XmlAttribute
+ private String user = null;
+
+ @XmlAttribute
+ private String password = null;
+
+ public String getUser() {
+ return user;
+ }
+
+ public String getPassword() {
+ return password;
+ }
+ }
+
+ @XmlAttribute
+ private String name = null;
+
+ @XmlAttribute(name = "url")
+ private String urlString = null;
+
+ private transient URL url = null;
+
+ @XmlAttribute
+ private IpCamMode mode = IpCamMode.PULL;
+
+ @XmlElement(name = "auth")
+ private AuthParams authParams = null;
+
+ private transient IpCamAuth auth = null;
+
+ public String getName() {
+ return name;
+ }
+
+ public URL getURL() {
+ if (urlString != null && url == null) {
+ try {
+ url = new URL(urlString);
+ } catch (MalformedURLException e) {
+ throw new WebcamException(e);
+ }
+ }
+ return url;
+ }
+
+ public IpCamMode getMode() {
+ return mode;
+ }
+
+ public IpCamAuth getAuth() {
+ if (authParams != null && auth == null) {
+ auth = new IpCamAuth(authParams.getUser(), authParams.getPassword());
+ }
+ return auth;
+ }
+}
diff --git a/webcam-capture-drivers/webcam-capture-driver-ipcam/src/test/resources/logback.xml b/webcam-capture-drivers/webcam-capture-driver-ipcam/src/test/resources/logback.xml
index 8bae4eb7..dea70d74 100644
--- a/webcam-capture-drivers/webcam-capture-driver-ipcam/src/test/resources/logback.xml
+++ b/webcam-capture-drivers/webcam-capture-driver-ipcam/src/test/resources/logback.xml
@@ -11,7 +11,6 @@
-
diff --git a/webcam-capture/pom.xml b/webcam-capture/pom.xml
index 4729be64..3cdbe799 100644
--- a/webcam-capture/pom.xml
+++ b/webcam-capture/pom.xml
@@ -87,13 +87,13 @@
ch.qos.logback
logback-classic
- 1.0.7
+ 1.0.9
provided
junit
junit
- 4.10
+ 4.11
test
diff --git a/webcam-capture/src/main/java/com/github/sarxos/webcam/Webcam.java b/webcam-capture/src/main/java/com/github/sarxos/webcam/Webcam.java
index f8a64dc0..60b4eb2c 100644
--- a/webcam-capture/src/main/java/com/github/sarxos/webcam/Webcam.java
+++ b/webcam-capture/src/main/java/com/github/sarxos/webcam/Webcam.java
@@ -48,7 +48,7 @@ public ShutdownHook(Webcam webcam) {
@Override
public void run() {
- LOG.info("Automatic resource deallocation");
+ LOG.info("Automatic {} deallocation", webcam.getName());
super.run();
webcam.dispose();
webcam.close0();
diff --git a/webcam-capture/src/main/java/com/github/sarxos/webcam/WebcamPanel.java b/webcam-capture/src/main/java/com/github/sarxos/webcam/WebcamPanel.java
index 040c10d7..e54a1c08 100644
--- a/webcam-capture/src/main/java/com/github/sarxos/webcam/WebcamPanel.java
+++ b/webcam-capture/src/main/java/com/github/sarxos/webcam/WebcamPanel.java
@@ -1,7 +1,9 @@
package com.github.sarxos.webcam;
+import java.awt.AlphaComposite;
import java.awt.BasicStroke;
import java.awt.Color;
+import java.awt.Dimension;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
@@ -105,6 +107,25 @@ public void paintPanel(WebcamPanel owner, Graphics2D g2) {
@Override
public void paintImage(WebcamPanel owner, BufferedImage image, Graphics2D g2) {
+
+ int w = getWidth();
+ int h = getHeight();
+
+ if (fillArea && image.getWidth() != w && image.getHeight() != h) {
+
+ BufferedImage resized = new BufferedImage(w, h, BufferedImage.TYPE_3BYTE_BGR);
+ Graphics2D gr = resized.createGraphics();
+ gr.setComposite(AlphaComposite.Src);
+ gr.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
+ gr.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
+ gr.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
+ gr.drawImage(image, 0, 0, w, h, null);
+ gr.dispose();
+ resized.flush();
+
+ image = resized;
+ }
+
g2.drawImage(image, 0, 0, null);
}
}
@@ -158,15 +179,26 @@ public void run() {
while (webcam.isOpen()) {
- image = webcam.getImage();
- if (image == null) {
- LOG.error("Image is null");
- }
+ BufferedImage tmp = webcam.getImage();
try {
- if (paused) {
- synchronized (this) {
- this.wait();
+
+ if (tmp == null) {
+
+ if (webcam.isOpen()) {
+ break;
+ }
+
+ LOG.error("Image is null");
+
+ } else {
+
+ image = tmp;
+
+ if (paused) {
+ synchronized (this) {
+ this.wait();
+ }
}
}
@@ -181,6 +213,8 @@ public void run() {
}
}
+ private boolean fillArea = false;
+
/**
* Painting frequency.
*/
@@ -242,6 +276,22 @@ public WebcamPanel(Webcam webcam) {
* @param start true if webcam shall be automatically started
*/
public WebcamPanel(Webcam webcam, boolean start) {
+ this(webcam, null, start);
+ }
+
+/**
+ * Creates new webcam panel which display image from camera in you your
+ * Swing application. If panel size argument is null, then image size will
+ * be used. If you would like to fill panel area with image even if its size
+ * is different, then you can use {@link #setFillArea(boolean)) method to
+ * configure this.
+ *
+ * @param webcam the webcam to be used to fetch images
+ * @param size the size of panel
+ * @param start true if webcam shall be automatically started
+ * @see WebcamPanel#setFillArea(boolean)
+ */
+ public WebcamPanel(Webcam webcam, Dimension size, boolean start) {
if (webcam == null) {
throw new IllegalArgumentException(String.format("Webcam argument in %s constructor cannot be null!", getClass().getSimpleName()));
@@ -252,7 +302,11 @@ public WebcamPanel(Webcam webcam, boolean start) {
repainter.setName(String.format("%s-repainter", webcam.getName()));
- setPreferredSize(webcam.getViewSize());
+ if (size == null) {
+ setPreferredSize(webcam.getViewSize());
+ } else {
+ setPreferredSize(size);
+ }
if (start) {
if (!webcam.isOpen()) {
@@ -399,4 +453,25 @@ public void setFPS(double frequency) {
public boolean isStarting() {
return starting;
}
+
+ /**
+ * Image will be resized to fill panel area if true. If false then image
+ * will be rendered as it was obtained from webcam instance.
+ *
+ * @param fillArea shall image be resided to fill panel area
+ */
+ public void setFillArea(boolean fillArea) {
+ this.fillArea = fillArea;
+ }
+
+ /**
+ * Get value of fill area setting. Image will be resized to fill panel area
+ * if true. If false then image will be rendered as it was obtained from
+ * webcam instance.
+ *
+ * @return True if image is being resized, false otherwise
+ */
+ public boolean isFillArea() {
+ return fillArea;
+ }
}
\ No newline at end of file