Like many self-proclaimed geeks, I can't resist a change to play with new technology. So when the Raspberry Pi 2 was released a short time ago, I didn't hesitate buying one. My first impressions was: for $35, that's a lot of computer power in a very small package. And because I really am a geek, I will admit that the first thing I tried to do with it was to install DOSBOX and run Microsoft Flight Simulator 4.
Once I got that out of my system, I started experimenting with some simple Java programming and the Raspberry Pi camera module. (It's great that Java is built-into Raspian Wheezy; in the past you had to install it.)
That being said, there isn't any direct I/O control of the camera via Java, although that's pretty much expected. When considering ways to control the camera I came across the Pi4J library, which provides Java-based APIs to control the Raspberry Pi's I/O. This looks like it will be great for me eventually, but for the moment the best idea that I could come up with was to write a simple Java-based wrapper class for the raspistill command line executable.
With that in mind, here's a sample class that you can use to take photos from Java on a Raspberry Pi. I added lots of code comments to explain how everything works, and I'll provide a little more detail after the code sample.
// This class is a very simple Java wrapper for the raspistill executable,
// which makes it easier to take photos from a Java application. Note that
// there are considerably more parameters available for raspistill which
// could be added to this class. (e.g. Shutter Speed, ISO, AWB, etc.)
public class RaspiStill
{
// Define the path to the raspistill executable.
private final String _raspistillPath = "/opt/vc/bin/raspistill";
// Define the amount of time that the camera will use to take a photo.
private final int _picTimeout = 5000;
// Define the image quality.
private final int _picQuality = 100;
// Specify a default image width.
private int _picWidth = 1024;
// Specify a default image height.
private int _picHeight = 768;
// Specify a default image name.
private String _picName = "example.jpg";
// Specify a default image encoding.
private String _picType = "jpg";
// Default class constructor.
public void RaspiStill()
{
// Do anything else here. For example, you could create another
// constructor which accepts an alternate path to raspistill,
// or defines global parameters like the image quality.
}
// Default method to take a photo using the private values for name/width/height.
// Note: See the overloaded methods to override the private values.
public void TakePicture()
{
try
{
// Determine the image type based on the file extension (or use the default).
if (_picName.indexOf('.')!=-1) _picType = _picName.substring(_picName.lastIndexOf('.')+1);
// Create a new string builder with the path to raspistill.
StringBuilder sb = new StringBuilder(_raspistillPath);
// Add parameters for no preview and burst mode.
sb.append(" -n -bm");
// Configure the camera timeout.
sb.append(" -t " + _picTimeout);
// Configure the picture width.
sb.append(" -w " + _picWidth);
// Configure the picture height.
sb.append(" -h " + _picHeight);
// Configure the picture quality.
sb.append(" -q " + _picQuality);
// Specify the image type.
sb.append(" -e " + _picType);
// Specify the name of the image.
sb.append(" -o " + _picName);
// Invoke raspistill to take the photo.
Runtime.getRuntime().exec(sb.toString());
// Pause to allow the camera time to take the photo.
Thread.sleep(_picTimeout);
}
catch (Exception e)
{
// Exit the application with the exception's hash code.
System.exit(e.hashCode());
}
}
// Overloaded method to take a photo using specific values for the name/width/height.
public void TakePicture(String name, int width, int height)
{
_picName = name;
_picWidth = width;
_picHeight = height;
TakePicture();
}
// Overloaded method to take a photo using a specific value for the image name.
public void TakePicture(String name)
{
TakePicture(name, _picWidth, _picHeight);
}
// Overloaded method to take a photo using specific values for width/height.
public void TakePicture(int width, int height)
{
TakePicture(_picName, width, height);
}
}
The wrapper class should be pretty self-explanatory: calling the TakePicture() method with no parameters will use the application defaults, and calling the overloaded methods will allow you to specify the output filename and the width/height for the image. You specify the image type based on the file extension; (e.g. ".jpg", ".png", ".gif"). There are a bunch of additional raspistill options which you can easily add to the application; see the Raspberry Pi camera module page for more information.
Here's a simple application to test it out:
public class CameraTest
{
// Define the number of photos to take.
private static final long _numberOfImages = 5;
// Define the interval between photos.
private static final int _delayInterval = 5000;
public static void main(String[] args)
{
try
{
// Create a new RaspiStill object.
RaspiStill camera = new RaspiStill();
// Loop through the number of images to take.
for (long i = 0; i < _numberOfImages; ++i)
{
// Capture the image.
camera.TakePicture("image" + i + ".jpg",800,600);
// Pause after each photo.
Thread.sleep(_delayInterval);
}
}
catch (Exception e)
{
// Exit the application with the exception's hash code.
System.exit(e.hashCode());
}
}
}
Now that I've shared this odd little sample, I'll wander back to my dungeon so I can keep playing with my Raspberry Pi.
Note: This blog was originally posted at http://blogs.msdn.com/robert_mcmurray/