PGraphics color and saving

Trying to get offscreen graphics working. Two issues I’m running into:

(1) The coloring is off. HSB(0, 100, 100) should be a nice bright red. And when I draw directly on the main canvas, it is. Drawing to pg first and then composing onto the screen turns it into a gray/green color.

(2) I can’t find a way to get it to save as anything but a completely black image. I saw a workaround posted for an earlier release that suggested pulling it into a PImage first, so I tried that, but it doesn’t help. Neither does the async disable hint.

Hopefully I’m missing something obvious here!

    private PGraphics pg;

    public void settings() {
        size(400, 400, P2D);
    }

    public void setup() {
        pg = createGraphics(200, 200, P2D);
        pg.hint(PConstants.DISABLE_ASYNC_SAVEFRAME);
        pg.smooth(8);
        pg.colorMode(HSB, 360, 100, 100, 1.0f);
        colorMode(HSB, 360, 100, 100, 1.0f);
    }

    public void draw() {
        pg.beginDraw();
        pg.fill(0, 100, 100);
        pg.rect(0,0, pg.width,pg.height);
        pg.endDraw();

        // this works
        image(pg, 0,0); 
        
        // this doesn't work (saves completely black image)
        pg.save("C:\\temp\\foo.png"); 
        
        // this doesn't work either
        PImage pi = pg.get();
        pi.save("C:\\temp\\foo.png"); 
        
        noLoop();
    }
1 Like

Had a go at this.

Apparently, P2D or any of the other documented renderers for createGraphics doesn’t work? (P2D, P3D, SVG and maybe PDF. I couldn’t test PDF because of some other error I didn’t resolve atm). Tried FX2D but that didn’t work either.

But if you don’t specify one, it works. I don’t know what renderer it uses then.

Also, use colorMode after beginDraw.

private PGraphics pg;

public void settings() {
  size(400, 400, P2D);
}

public void setup() {
  colorMode(HSB, 360, 100, 100, 1.0f);
}

public void draw() {
  pg = createGraphics(200, 200);
  //pg.hint(PConstants.DISABLE_ASYNC_SAVEFRAME);
  pg.smooth(8);

  pg.beginDraw();
  pg.colorMode(HSB, 360, 100, 100, 1.0f);

  pg.fill(0, 100, 100);
  pg.rect(0, 0, pg.width-1, pg.height-1);
  pg.endDraw();

  // this works
  image(pg, 0, 0); 

  // this doesn't work (saves completely black image)
  pg.save("foo.png"); 

  // this doesn't work either
  //PImage pi = pg.get();
  //pi.save("foo.png"); 

  noLoop();
}
1 Like

Thanks for taking a look!

Code diving says

    public PGraphics createGraphics(int w, int h) {
        return this.createGraphics(w, h, "processing.awt.PGraphicsJava2D");
    }

So, I guess this is a bug. The docs specifically say you should be able to createGraphics with other renderers.

Reported issue https://github.com/processing/processing/issues/6094.

I know that some stuff like pg.fill(); works outside, but it seems colorMode doesn’t.

-> put it in between beginDraw() and endDraw(). works for me.

PGraphics pg;
public void settings() {
  size(400, 400, P2D);
}
public void setup() {
  pg = createGraphics(200, 200, P2D);
  pg.beginDraw();
  pg.colorMode(HSB, 100, 100, 100, 255);
  pg.endDraw();        
  colorMode(HSB, 100, 100, 100, 255);
}

public void draw() {
  pg.beginDraw();
  pg.fill(0, 100, 100);
  pg.rect(0, 0, pg.width, pg.height);
  pg.endDraw();
  // this works
  image(pg, 0, 0);        
  // this doesn't work (saves completely black image)
  pg.save("redimage.png"); 
  noLoop();
}
1 Like

Yes, thanks for clarifying. Moving the colorMode to after beginDraw fixes that aspect of my problem. The issue I opened is just for the black image on save.

that would be an error I cannot help fix. for me, saving it works properly, I get the image in red…the only thing I can think of is trying other formats, but you probably did that already

Are you on a different platform? I’m on Windows.

yes I am, I use Mac osx

dzaima on github found the problem – you need to call save() before endDraw().

3 Likes

ah, that’s probably the good way :slight_smile:
maybe it works too when you but it into its own begin… and end…
I guess one wants to call the save from elsewhere too, like inside keypressed();