How do I draw something and then save it as an Image?

When I draw something on a custom offscreen PGraphics and then save the file it is a blank image with alpha 0 on all pixels.
How is PImage and PGraphics supposed to be used to save an image drawn?
Worth mentioning is that I want to draw to an offscreen PGraphics since the main PGraphics is used for displaying other info.

1 Like

When we want to alter a PGraphic we add the name of that particular object in front of functions (see PGraphics reference as an example). We can apply that same principle with the save() function.

Does that do what you had in mind?

well, i draw onto pgraphics using its methods ( rect, image, etc ) but when i save it as a .png, it’s a blank file with all alpha on 0 ( all on 0, basically default value )

can you make a short but complete code example
what shows us the way you use PGraphics
and produces that faulty .png file ?


https://processing.org/reference/PGraphics.html
https://processing.org/reference/save_.html

1 Like

on mobile

pgraphics g = new pgraphics()
g.rect(0,0,10,10)
g.save (“1.png”)

also tried creategraphics( 200,500) but to no avail

It works for this example, which saves the PGraphic as a red, 100 x 100 png file:

PGraphics pg;

void setup() {
  size(400, 400);
  noLoop();
  pg = createGraphics(100, 100);
}

void draw() {
  background(250);
  pg.beginDraw();
  pg.background(255, 0, 0);
  pg.endDraw();
  pg.save("test.png");
}

If you can’t get it to work for your sketch please share your code once you’re at you computer :slight_smile:

4 Likes

ah so the begindraw and enddraw are required. that was probably the problem. probs to you.
i was tired of using the slow workaround that converted it into a java bufferedimage.
ill try it when im on pc

1 Like

That’s right.

The beginDraw() and endDraw() methods (see above example) are necessary to set up the buffer and to finalize it.

You will sometimes get an error if you don’t call beginDraw – but sometimes you don’t. If you don’t call endDraw, however, your drawing hasn’t been finalized, so you are probably saving an empty buffer.

This is similar in some ways to pixel manipulation with loadPixels, savePixels – on the main canvas or on a PImage.

4 Likes

this is understandable, and @Tiemen show you how to do it correcty,
but the way to develop coding ?
stay closer to the reference & examples until you get it working…

may i suggest to:

  • first show what you draw ( even only for diagnostic with a disable logic )
  • and save on demand / if ok / only…
PGraphics pg;
int pgw=100, pgh=100;                                              // adjust here picture size in pix
boolean diagi = true, diagpg = true;                               // diagnostic switches
long intro = 8000;                                                 // show key operation for 8 sec 
String outfile = "data/pg.png";                                    // save() creates the directory if not exists

void make_pg() {
  pg = createGraphics(pgw, pgh);
  pg.beginDraw();
  pg.background(200, 200, 0);
  pg.fill(0, 200, 0);
  pg.stroke(0, 200, 200);
  pg.strokeWeight(10);
  pg.circle(pgw/2, pgh/2, pgw/2-10);
  pg.endDraw();
}

void setup() {
  size(400, 400);
  make_pg();
  fill(0);
}

void draw() {
  background(200);
  if ( diagpg )                                                     // show the pg first for check
    image(pg, 10, 10); 
  if ( diagi  )                                                     // show info at startup
    text("use: key [s] save pg as picture, [p] toggle show it on canvas", 10, height-20);
  timer();
}

void keyPressed() {
  if ( key == 's' ) pg.save(outfile);
  if ( key == 'p' ) diagpg = ! diagpg;
}

void timer() {
  if ( diagi && millis() > intro ) diagi = false;
}

1 Like

So when I draw on the main canvas without begin draw and end draw it is basically drawing with no buffers?

you still owe us your code,
as i am not able to reproduce that empty file
with anything like your from mobile posted text.

you might have found a leak?

using createGraphics without beginDraw actually results in a null pointer on the image field in PGraphics.
I expected PGraphics to save from the pixels of PImage but PGraphicsJava2D actually overwrites loadPixels and has an own Image field which is probably written to when I use beginDraw / endDraw.

PGraphics pg = new PGraphics();

pg.setSize( 50, 50 );

pg.rect( 0, 0, 10, 10 );

pg.save( dataPath( “a.png” ) );

thanks,
so the

pg.setSize( 50, 50 );

make the THING to run without error
but not produce a content in the picture file

where did you find that
< PGraphics >.setSize()

?working? command?

_
because

PGraphics pg = new PGraphics();
pg = createGraphics(100, 100);
//pg.setSize( 50, 50 );
pg.beginDraw();
pg.rect( 0, 0, 10, 10 );
//pg.endDraw();
pg.save( dataPath( "a.png" ) );

works,
but requires beginDraw
works without endDraw() funny???


i think it just change the size, but not creates a buffer.
sadly the drawing to a not existing buffer gives no error???

anyhow a good way to use it would be:

PGraphics pg = new PGraphics();
pg = createGraphics(0,0);
pg.setSize( 50, 50 );
pg.beginDraw();
pg.rect( 0, 0, 10, 10 );
pg.endDraw();
image(pg,0,0);
pg.save( dataPath( "a.png" ) );

does it produce an empty image without enddraw?

that is strange,

PGraphics pg;
pg = createGraphics(0,0);
pg.setSize( 50, 50 );
pg.beginDraw();
pg.rect( 0, 0, 10, 10 );
//pg.endDraw();
image(pg,0,0);
pg.save("data/a.png");

as you can test in seconds yourselves
this produces a picture file with rect shown,
BUT it not show the rect in the canvas.
for this the endDraw() is required.