Skip to content

Commit

Permalink
Add image transformation feature, closes #73
Browse files Browse the repository at this point in the history
  • Loading branch information
sarxos committed Mar 20, 2013
1 parent a80b180 commit 5720087
Show file tree
Hide file tree
Showing 4 changed files with 171 additions and 65 deletions.
@@ -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();
}

}
169 changes: 105 additions & 64 deletions webcam-capture/src/main/java/com/github/sarxos/webcam/Webcam.java
Expand Up @@ -117,6 +117,11 @@ public class Webcam {
*/
private WebcamUpdater updater = new WebcamUpdater(this);

/**
* IMage transformer.
*/
private volatile WebcamImageTransformer transformer = null;

/**
* Webcam class.
*
Expand Down Expand Up @@ -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?
*
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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());
}

/**
* <b>CAUTION!!!</b><br>
* <br>
Expand Down Expand Up @@ -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;
}
}
@@ -0,0 +1,10 @@
package com.github.sarxos.webcam;

import java.awt.image.BufferedImage;


public interface WebcamImageTransformer {

BufferedImage transform(BufferedImage image);

}
Expand Up @@ -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
Expand Down

0 comments on commit 5720087

Please sign in to comment.