Simple Java Wrapper Class for raspistill on the Raspberry Pi 2
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.