Search code examples
processing

Saving frame to file without rendering in processing


In Processing, how can I modify an existing sketch which saves each frame to an image file so that it does not render to the screen?

I saw in https://forum.processing.org/one/topic/how-can-i-save-calculate-frame-without-displaying-them-in-real-time.html that you can use PGraphics to draw graphics into an offline buffer, which seems like it would be what I am after, but I am not sure how I can easily modify my existing sketch to use the PGraphics class in that way.

On top of this, I would like the option to render to screen as well if needed by setting a toggle variable.

Is there an easy way of "retrofitting" an existing sketch so that it can use PGraphics instead of the default rendering method (say, in the setup method) so I don't have to go into my sketch and change every single draw command?


Solution

  • You can use a PGraphics object and draw on it just like you would with a canvas. Here's an example sketch with no draw loop which outputs an image file:

    void setup() {
      PGraphics pg = createGraphics(150, 150);
      
      pg.beginDraw();
      pg.background(255);
      pg.stroke(0);
      pg.fill(color(0, 0, 200));
      pg.rect(50, 50, 50, 50);
      pg.endDraw();
      
      pg.save("fileName.png");
    }
    

    In my sketch's folder, it created this file:

    Saved image

    About the other question: I don't think that you can retrofit a written draw loop into a similar output without rendering it in the sketch's window without heavily modifying the code, BUT... if your goal is yo be able to choose between drawing to the sketch window or to a file, you can draw in PGraphics every frame and choose whether if you want to show the PGraphics or not depending on your business rules. You'll still have a lot of refactoring to do, but it's unavoidable.

    Here's the same example than before, but implementing this idea:

    boolean showFrame = true;
    boolean saveFrame = false;
    
    void setup() {
      size(150, 150);
    }
    
    void draw() {
      PGraphics pg = createGraphics(150, 150);
      
      pg.beginDraw();
      pg.background(255);
      pg.stroke(0);
      pg.fill(color(0, 0, 200));
      pg.rect(50, 50, 50, 50);
      pg.endDraw();
      
      if (showFrame) {image(pg, 0, 0);}
      if (saveFrame) {pg.save("fileName.png");}
    }
    

    Hope this helps. Have fun!