NullPointerException when calling save() after surface.setSize() in P2D

Thanks for asking. This got me to look more closely at the program I’d left tagged as “not getting proper pixel density”, and showed me that it was something totally different.

Here are three circles that seemed like they should be identical, but aren’t:

29%20PM

and here’s the code that generated them:

void setup() {
  background(0);
}

void draw() {
}

void mousePressed() {
  // Create a mask.
  PGraphics mask = createGraphics(20, 20);
  mask.beginDraw();
  mask.background(255);
  mask.endDraw();

  // Draw onto the default PGraphics.
  noStroke();
  fill(255);
  ellipse(20, 50, 20, 20);

  // Draw onto a new PGraphics.
  PGraphics c1 = createGraphics(20, 20);
  c1.beginDraw();
  c1.background(0);
  c1.noStroke();
  c1.fill(255);
  c1.ellipse(10, 10, 20, 20);
  c1.mask(mask);
  c1.endDraw();
  image(c1, 40, 40);

  // Draw onto a new PGraphics.
  PGraphics c2 = createGraphics(20, 20);
  c2.beginDraw();
  c2.background(0, 0);  // transparent
  c2.noStroke();
  c2.fill(255);
  c2.ellipse(10, 10, 20, 20);
  c2.mask(mask);
  c2.endDraw();
  image(c2, 70, 40);
}

As you can see, pixel density doesn’t even come up. The difference is that the blurry circle was drawn using a transparent background, and when I applied a mask to it (which seems like it should have been a no-op, since the mask was all white), the edges lost any semblance of anti-aliasing.

This is pretty far afield from my initial question, obviously. I’ve found better ways of doing this since I wrote it, but I’m still curious about a couple things:

  • Why does the transparent background lead to a badly masked image?
  • Why does the left circle (drawn plainly using ellipse()) also turn into the bad octagon-thing if I call it in draw(), as opposed to just drawing it once in mousePressed()?

Grateful for any ideas.