Constant Contact Labs Developer Blog

  • How to Use Processing from the Command Line to Generate Images Posted Thursday, January 7, 2010 Jim Garretson 8 Comments

    Processing logo

    The Processing project provides a great Java-based visual programming environment with a number of compelling features, including cross-platform support and OpenGL-accelerated graphics. We’ve used it at Constant Contact Labs for a number of internal data visualization projects, and it’s worked very well for us. Lately we’ve had reason to work out a way to have it run in a “headless,” command-line-driven mode for periodic graph generation. Read on for the method and code.

    First, About Processing

    Briefly, Processing is a Java-based programming language designed expressly for the creation of rich visuals - for example, images, interactive graphics, and animations. It normally runs as either a desktop Java application or as an applet embedded in a web page. It’s supported for Windows, Mac and Linux, provided a Java VM is available. You can learn more at processing.org.

    Example Labs Uses

    At Constant Contact Labs, we’ve used Processing for a few small internal data visualization projects: for example, we’re using it on a daily basis to present a map of the world with live web site traffic overlaid:

    Live Site Traffic

    We’re also using it embedded as an applet in a web page to provide a Google Maps-style floorplan directory of our offices:

    Floorplan

    Generating Images from the Command Line

    Processing works well for generating live and interactive graphics, but for various reason we’d also like to use it to generate custom graphs for server monitoring purposes. For this, we need to write a Java application that can run as a headless batch job over SSH, regularly generating PNG images representing the current state of the system. Here’s an example of the type of graph we can build using Processing (this is just sample data):

    To generate an image without a windowing system, you’ll need to step outside of the Processing IDE and build a straight Java application. You’ll need to subclass the main Processing graphics object, PApplet, in order to retrieve a graphics context for drawing. Fortunately, this is pretty straightforward to do. Here’s code for a simple GraphRenderer.java, that draws a sample image and saves it out to the filesystem with a given filename:

    import processing.core.*;
    
    public class GraphRenderer
    {
    
        // our headless Processing applet, to which we're drawing
        private PApplet applet = null;
    
        // the graphics context of the applet - all drawing operations are performed on this object
        private PGraphics context = null;
        
        
        GraphRenderer()
        {
            // this space intentionally left blank
        } // constructor
        
        
        void initialize(int _width, int _height)
        {
            // create a PApplet object and retrieve its graphics context
            applet = new PApplet();        
            context = applet.createGraphics(_width, _height, PApplet.P3D);
            applet.g = context;
        } // initialize
    
        
        // call this function to perform drawing operations and save the results to an image.
        void render(String _filename)
        {
            if (applet == null || context == null)
            {
                System.out.println("error: GraphRenderer::render(): call initialize() before rendering.");
                return;
            }
            
    	// tell the context we're starting to draw
            context.beginDraw();
            
            // perform drawing using normal Processing methods
            context.background(0);
            context.fill(255);
            context.noStroke();
            context.beginShape();
                context.vertex(100,100);
                context.vertex(300,100);
                context.fill(0);
                context.vertex(300,300);
                context.vertex(100,300);
            context.endShape();
            
    	// tell the context we're finished drawing
            context.endDraw();
            
    	// save the contents of the rendering context to a file
            context.save(_filename);
            
        } // render
        
        
    } // class GraphRenderer
    

    Now that we’ve created a GraphRenderer class, we just need a main to instantiate it and tell it what to do. Here’s Grapher.java:

    public class Grapher
    {
        
        public static void main(String args[])
        {
    	// create a GraphRenderer object
            GraphRenderer g = new GraphRenderer();
    
    	// initialize it, passing the length and width of the desired target image
            g.initialize(400, 400);
    
    	// have the GraphRenderer render out to a file; the file extension determines the output format
            g.render("test.png");	
        }    
    } // class Grapher
    

    From the command line you can build this example using:

    javac Grapher.java GraphRenderer.java
    

    To run it, use:

    java Grapher
    

    A file, test.png, will be created in the working directory. Here’s what it looks like:

    This image corresponds to the drawing commands issued in GraphRenderer::render().

    Wrapping Up

    This example has demonstrated one way to use the Processing environment from within a standard Java application to generate images. Hopefully this example will be useful to you. I’ll be happy to answer any questions or comments - please feel free to post up below.

     
    The opinions expressed here represent those of the author and not those of Constant Contact, Inc. Read Blog Terms
    Next Post Previous Post
     

Comments (8) +comment on this post
 

  • Jim Garretson | 1:55 PM January 14, 2010

    Side note: If you need to run an applet on a machine without an X11 display set up, the easiest way to avoid Java problems is to install and run Xvfb as referenced here: http://processing.org/discourse/yabb2/YaBB.pl?num=1193317878/9#9

  • Matthew Shanley | 1:55 PM January 18, 2010

    Jim, did you look into ImageMagick or other traditional headless graphic generation tools? I’m wondering how Processing compares in terms of things like ease of programming and performance.

  • Jim Garretson | 3:15 PM January 18, 2010

    Matt, the main draw in this case was that we’ve already developed a good amount of drawing and related classes for live display in Processing, so coming up with a way to generate output images allowed us to reuse the entirety of the drawing code and a good 75% of the overall app architecture. If you’re starting from scratch, I can definitely see the appeal of ImageMagick and its brethren, but in our case the ability to provide GL-accelerated live visualizations as well as static images from the same codebase led me to take this approach.

    As far as programming and performance comparisons go, it depends very much on your background. Processing is quite easy to adapt to if you’re familiar with Java, but it hasn’t anywhere near the number of interfaces for other languages that IM does.

  • hotsystemutilities | 2:50 AM October 7, 2010

    Great website man…thanks for the post…this article was really great…keep on posting such stuff…great work…. http://www.hotsystemutilities.com

  • David F. Houghton | 8:30 AM June 13, 2011

    I’d just like to say thanks for posting this. You’ve saved me a good bit of hair pulling.

  • Jim Garretson | 8:52 AM June 13, 2011

    Happy to hear it, David!

  • Shahzad Khan | 8:16 AM October 27, 2011

    This was very nice. I managed to follow a derivative of the method to create word clouds using WordCram by calling processing from my web based java program.

    Thank you for sharing.

  • mattgenton | 9:16 PM January 2, 2012

    hi to all at http://www.ctctlabs.com  i thought i had sent this newyears eve but it didnt send so i have sent it again happy new year   to all of you      
    - matty

Add your comment below

Remember me

Please enter the word you see in the image below:


*  Please be aware that all comments are moderated.

Interested in a particular topic?

If there are specific topics you’d like to see us discuss on our blog or other ideas you’d like to share, please let us know. Click here to contact us.