3/11/12

Serving camera images with RESTful Web Service

I've used Restlet and XStream to write RESTful web service for serving camera images.


Source code:

import neo.imaging.ImageCapture;

import org.restlet.Server;
import org.restlet.data.Protocol;
import org.restlet.resource.Get;
import org.restlet.resource.ServerResource;

/**
* Web service for serving usb camera images.
*
* @author neo
*/
public class CameraServerResource extends ServerResource {

/* State */

private final ImageCapture ic = ImageCapture.getInstance();
private final BufferedImageSerializer bis = BufferedImageSerializer.getInstance();

/* Web service methods */

@Get
public String toString() {
return bis.toXML(ic.getCurrentImage());
}

/* Application entry point */

/**
* Entry point of server application.
*/
public static void main(String[] args) throws Exception {
// Create the HTTP server and listen on port 8182
new Server(Protocol.HTTP, 8182, CameraServerResource.class).start();
}

}






import java.awt.image.BufferedImage;
import java.awt.image.DataBufferInt;
import java.nio.IntBuffer;

import org.gstreamer.Caps;
import org.gstreamer.Element;
import org.gstreamer.ElementFactory;
import org.gstreamer.Gst;
import org.gstreamer.Pipeline;
import org.gstreamer.State;
import org.gstreamer.elements.RGBDataSink;

/**
* Singleton that captures usb camera image, and stores it in currentImage
* variable, which is accessible through getCurrentImage() method.
*
* @author neo
*/
public class ImageCapture {

/* Synchronization lock */

final Object lock = new Object();

/* Instance */

private static ImageCapture instance = new ImageCapture();

/* State */

private Pipeline pipe;
private BufferedImage currentImage = null;

/* Image capture listener */

/**
* RGBDataSink listener responsible for capturing camera image and
* storing it in currentImage variable.
*/
RGBDataSink.Listener imageCaptureListener = new RGBDataSink.Listener() {
@Override
public void rgbFrame(boolean isPreRollImage, int width, int height,
IntBuffer rgb) {
synchronized (lock) {
currentImage = getBufferedImage(width, height);
copyDataToImage(rgb, currentImage, width, height);
}
}

private BufferedImage getBufferedImage(int width, int height) {
synchronized (lock) {
BufferedImage bufferedImage = new BufferedImage(width,
height, BufferedImage.TYPE_INT_RGB);
bufferedImage.setAccelerationPriority(0.0f);
return bufferedImage;
}
}

private void copyDataToImage(IntBuffer rgb, BufferedImage image,
int width, int height) {
synchronized (lock) {
int[] pixels = ((DataBufferInt) image.getRaster()
.getDataBuffer()).getData();
rgb.get(pixels, 0, width * height);
}
}
};

/* Constructors */

private ImageCapture() {
preparePipeline(new String[] {});
play();
};

/* Singleton instance accessor */

public static ImageCapture getInstance() {
return instance;
}

/* Methods */

/**
* @return last captured camera image.
*/
public final BufferedImage getCurrentImage() {
synchronized (lock) {
return currentImage;
}
}

/**
* Starts image capture pipeline processing (allocating resources).
*/
public void play() {
synchronized (lock) {
pipe.setState(State.PLAYING);
}
}

/**
* Stops image capture pipeline processing (deallocating resources).
*/
public void stop() {
synchronized (lock) {
pipe.stop();
}
}

/**
* Initializes image capture pipeline.
*/
private synchronized void preparePipeline(String[] args) {
synchronized (lock) {
args = Gst.init("SwingVideoTest", args);
pipe = new Pipeline("pipeline");
ElementFactory.make("videotestsrc", "source");
final Element videosrc = ElementFactory.make("v4l2src", "source");
final Element videofilter = ElementFactory
.make("capsfilter", "flt");
videofilter
.setCaps(Caps
.fromString("video/x-raw-rgb, framerate = 25/1, width=320, height=240"));
final RGBDataSink videosink = new RGBDataSink("rgb",
imageCaptureListener);

pipe.addMany(videosrc, videofilter, videosink);
Element.linkMany(videosrc, videofilter, videosink);
}
}

}





import java.awt.color.ICC_ColorSpace;
import java.awt.color.ICC_Profile;
import java.awt.color.ICC_ProfileRGB;
import java.awt.image.BufferedImage;
import java.awt.image.DataBufferInt;
import java.awt.image.DirectColorModel;
import java.awt.image.SinglePixelPackedSampleModel;

import neo.imaging.ws.BufferedImageSerializer;

import com.thoughtworks.xstream.XStream;

/**
* Class responsible for serializing BufferedImage to XML format.
*
* @author neo
*/
class BufferedImageSerializer {

/* Singleton instance */

public static BufferedImageSerializer instance = new BufferedImageSerializer();

/* State */

private final XStream xs = new XStream(); // serialization engine

/* Constructor */

private BufferedImageSerializer() {
xs.alias("image", BufferedImage.class);
xs.alias("directColorModel", DirectColorModel.class);
xs.alias("iccColorSpace", ICC_ColorSpace.class);
xs.alias("iccProfileRGB", ICC_ProfileRGB.class);
xs.alias("iccProfile", ICC_Profile.class);
xs.alias("singlePixelPackedSampleModel", SinglePixelPackedSampleModel.class);
xs.alias("dataBufferInt", DataBufferInt.class);
}

/* Singleton instance accessor */

public static BufferedImageSerializer getInstance() {
return instance;
}

/* Serialization method */

public String toXML(final BufferedImage img) {
return xs.toXML(img);
}
}

No comments:

Post a Comment