diff --git a/webcam-capture/src/example/java/com/github/sarxos/webcam/example/ImageTransformerExample.java b/webcam-capture/src/example/java/com/github/sarxos/webcam/example/ImageTransformerExample.java
new file mode 100644
index 00000000..0846d6b9
--- /dev/null
+++ b/webcam-capture/src/example/java/com/github/sarxos/webcam/example/ImageTransformerExample.java
@@ -0,0 +1,46 @@
+package com.github.sarxos.webcam.example;
+
+import java.awt.image.BufferedImage;
+
+import javax.swing.JFrame;
+
+import com.github.sarxos.webcam.Webcam;
+import com.github.sarxos.webcam.WebcamImageTransformer;
+import com.github.sarxos.webcam.WebcamPanel;
+import com.github.sarxos.webcam.WebcamResolution;
+import com.github.sarxos.webcam.util.jh.JHGrayFilter;
+
+
+public class ImageTransformerExample implements WebcamImageTransformer {
+
+ private static final JHGrayFilter GRAY = new JHGrayFilter();
+
+ @Override
+ public BufferedImage transform(BufferedImage image) {
+ return GRAY.filter(image, null);
+ }
+
+ public ImageTransformerExample() {
+
+ Webcam webcam = Webcam.getDefault();
+ webcam.setViewSize(WebcamResolution.VGA.getSize());
+ webcam.setImageTransformer(this);
+ webcam.open();
+
+ JFrame window = new JFrame("Test Transformer");
+
+ WebcamPanel panel = new WebcamPanel(webcam);
+ panel.setFPSDisplayed(true);
+ panel.setFillArea(true);
+
+ window.add(panel);
+ window.pack();
+ window.setVisible(true);
+ window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+ }
+
+ public static void main(String[] args) {
+ new ImageTransformerExample();
+ }
+
+}
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 1aa18154..472a8186 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
@@ -117,6 +117,11 @@ public class Webcam {
*/
private WebcamUpdater updater = new WebcamUpdater(this);
+ /**
+ * IMage transformer.
+ */
+ private volatile WebcamImageTransformer transformer = null;
+
/**
* Webcam class.
*
@@ -262,6 +267,87 @@ public boolean close() {
return true;
}
+ /**
+ * Return underlying webcam device. Depending on the driver used to discover
+ * devices, this method can return instances of different class. By default
+ * {@link WebcamDefaultDevice} is returned when no external driver is used.
+ *
+ * @return Underlying webcam device instance
+ */
+ public WebcamDevice getDevice() {
+ assert device != null;
+ return device;
+ }
+
+ /**
+ * Completely dispose capture device. After this operation webcam cannot be
+ * used any more and full reinstantiation is required.
+ */
+ protected void dispose() {
+
+ assert disposed != null;
+ assert open != null;
+ assert driver != null;
+ assert device != null;
+ assert listeners != null;
+
+ if (!disposed.compareAndSet(false, true)) {
+ return;
+ }
+
+ open.set(false);
+
+ LOG.info("Disposing webcam {}", getName());
+
+ WebcamDisposeTask task = new WebcamDisposeTask(driver, device);
+ try {
+ task.dispose();
+ } catch (InterruptedException e) {
+ LOG.error("Processor has been interrupted before webcam was disposed!", e);
+ return;
+ }
+
+ WebcamEvent we = new WebcamEvent(WebcamEventType.DISPOSED, this);
+ for (WebcamListener l : listeners) {
+ try {
+ l.webcamClosed(we);
+ l.webcamDisposed(we);
+ } catch (Exception e) {
+ LOG.error(String.format("Notify webcam disposed, exception when calling %s listener", l.getClass()), e);
+ }
+ }
+
+ // hook can be null because there is a possibility that webcam has never
+ // been open and therefore hook was not created
+ if (hook != null) {
+ try {
+ Runtime.getRuntime().removeShutdownHook(hook);
+ } catch (IllegalStateException e) {
+ LOG.trace("Shutdown in progress, cannot remove hook");
+ }
+ }
+
+ LOG.debug("Webcam disposed {}", getName());
+ }
+
+ /**
+ * TRansform image using image transformer. If image transformer has not
+ * been set, this method return instance passed in the argument, without any
+ * modifications.
+ *
+ * @param image the image to be transformed
+ * @return Transformed image (if transformer is set)
+ */
+ protected BufferedImage transform(BufferedImage image) {
+ if (image != null) {
+ WebcamImageTransformer tr = getImageTransformer();
+ if (tr != null) {
+ return tr.transform(image);
+ }
+ }
+ return image;
+ }
+
/**
* Is webcam open?
*
@@ -412,7 +498,7 @@ public BufferedImage getImage() {
// get image
t1 = System.currentTimeMillis();
- BufferedImage image = new WebcamReadImageTask(driver, device).getImage();
+ BufferedImage image = transform(new WebcamReadImageTask(driver, device).getImage());
t2 = System.currentTimeMillis();
if (image == null) {
@@ -822,69 +908,6 @@ public static void registerDriver(String clazzName) {
DRIVERS_LIST.add(clazzName);
}
- /**
- * Return underlying webcam device. Depending on the driver used to discover
- * devices, this method can return instances of different class. By default
- * {@link WebcamDefaultDevice} is returned when no external driver is used.
- *
- * @return Underlying webcam device instance
- */
- public WebcamDevice getDevice() {
- assert device != null;
- return device;
- }
-
- /**
- * Completely dispose capture device. After this operation webcam cannot be
- * used any more and full reinstantiation is required.
- */
- protected void dispose() {
-
- assert disposed != null;
- assert open != null;
- assert driver != null;
- assert device != null;
- assert listeners != null;
-
- if (!disposed.compareAndSet(false, true)) {
- return;
- }
-
- open.set(false);
-
- LOG.info("Disposing webcam {}", getName());
-
- WebcamDisposeTask task = new WebcamDisposeTask(driver, device);
- try {
- task.dispose();
- } catch (InterruptedException e) {
- LOG.error("Processor has been interrupted before webcam was disposed!", e);
- return;
- }
-
- WebcamEvent we = new WebcamEvent(WebcamEventType.DISPOSED, this);
- for (WebcamListener l : listeners) {
- try {
- l.webcamClosed(we);
- l.webcamDisposed(we);
- } catch (Exception e) {
- LOG.error(String.format("Notify webcam disposed, exception when calling %s listener", l.getClass()), e);
- }
- }
-
- // hook can be null because there is a possibility that webcam has never
- // been open and therefore hook was not created
- if (hook != null) {
- try {
- Runtime.getRuntime().removeShutdownHook(hook);
- } catch (IllegalStateException e) {
- LOG.trace("Shutdown in progress, cannot remove hook");
- }
- }
-
- LOG.debug("Webcam disposed {}", getName());
- }
-
/**
* CAUTION!!!
*
@@ -979,4 +1002,22 @@ public static synchronized WebcamDiscoveryService getDiscoveryService() {
}
return discovery;
}
+
+ /**
+ * Return image transformer.
+ *
+ * @return Transformer instance
+ */
+ public WebcamImageTransformer getImageTransformer() {
+ return transformer;
+ }
+
+ /**
+ * Set image transformer.
+ *
+ * @param transformer the transformer to be set
+ */
+ public void setImageTransformer(WebcamImageTransformer transformer) {
+ this.transformer = transformer;
+ }
}
diff --git a/webcam-capture/src/main/java/com/github/sarxos/webcam/WebcamImageTransformer.java b/webcam-capture/src/main/java/com/github/sarxos/webcam/WebcamImageTransformer.java
new file mode 100644
index 00000000..9ea0d3ec
--- /dev/null
+++ b/webcam-capture/src/main/java/com/github/sarxos/webcam/WebcamImageTransformer.java
@@ -0,0 +1,10 @@
+package com.github.sarxos.webcam;
+
+import java.awt.image.BufferedImage;
+
+
+public interface WebcamImageTransformer {
+
+ BufferedImage transform(BufferedImage image);
+
+}
diff --git a/webcam-capture/src/main/java/com/github/sarxos/webcam/WebcamUpdater.java b/webcam-capture/src/main/java/com/github/sarxos/webcam/WebcamUpdater.java
index fd71e0ba..079fa823 100644
--- a/webcam-capture/src/main/java/com/github/sarxos/webcam/WebcamUpdater.java
+++ b/webcam-capture/src/main/java/com/github/sarxos/webcam/WebcamUpdater.java
@@ -156,10 +156,19 @@ public void run() {
// Calculate time required to fetch 1 picture.
+ WebcamDriver driver = Webcam.getDriver();
+ WebcamDevice device = webcam.getDevice();
+
+ assert driver != null;
+ assert device != null;
+
+ BufferedImage img = null;
+
t1 = System.currentTimeMillis();
- image.set(new WebcamReadImageTask(Webcam.getDriver(), webcam.getDevice()).getImage());
+ img = webcam.transform(new WebcamReadImageTask(driver, device).getImage());
t2 = System.currentTimeMillis();
+ image.set(img);
imageNew = true;
// Calculate delay required to achieve target FPS. In some cases it can