Default sketch object, PGraphics vs. PImage

edited December 2016 in Programming Questions

[Q1] Could somebody explain the differences between PGraphics and PImage? Are they related? I believe you can use them similarly but I am not clear when one is preferred than the other.

[Q2] When it comes to something simple as this:

void setup(){
  size(800,400); 
  fill(255)
}
void draw(){
  Background(0);
  ellipse(width*0.25,height*0.25,width*0.5,height*0.5);
}

Is processing creating a PImage object to host the current drawing commands? So when I call the get() function, I get access to this PImage?

Thxs for your comments,
Kf

Tagged:

Answers

  • edited December 2016 Answer ✓

    [A1] PImage is the parent class: https://Processing.org/reference/PImage.html
    While PGraphics is the child class: https://Processing.org/reference/PGraphics.html

    As long as the methods & fields from PImage are enough, you don't need PGraphics.

    BtW, there are 3rd-party libraries w/ classes which extend PImage too.
    For example classes Movie & Capture.

    [A2] Sketch's canvas is actually a PGraphics, which is rendered to the PSurface at the end of each draw() cycle. You can access it by calling getGraphics(). :-bd

  • [Q3] So technically PGraphics have access to PImage's methods as described in the reference here? I believe I have tried before and it complained it was not a PImage object. Could I do casting to convert a PGraphics to a PImage?

    [Q4] Now, I can load a PImage and then I can loadPixels to modify color information. Can I draw ellipses and other graphics commands on it?

    I know I can do that with PGraphics. However I need to explicitly call beginDraw() and endDraw(). I would say I will always use PGraphics if it wasn't for two details:

    1. The point I mentioned in my prev paragraph, not able to access PImage's method like get(), filter(), tint(), etc...
    2. Other objects uses PImage, as you @GoToLoop mention above.

    In contrast, PGraphics allows to manage transparency slightly different than PImage. I won't get into the details here as this could be another post. I might be wrong on this one anyways.

    So far, I have been able to use either object based on my task at hand. Now, I need to decide one over the other.

    [Q5] Is there a difference between using the set(), background() and image() methods when drawing a PImage object? I understand from the reference that set() suppose to be faster but to be used only if pixel information is not modified(from the loadPixels() reference). Any other difference?

    I am reviewing this link as it could clarify some of my questions: http://processing.github.io/processing-javadocs/core/

    Thxs,
    Kf

  • Thxs @GoToLoop for keeping my Q&A format btw :)>-

    Kf

  • edited December 2016 Answer ✓

    [Q3] & [Q4] Yes, by Java's inheritance rules, a subclass got everything its parent's class got!

    However, due to its more complex nature, a PGraphics may need to invoke its beginDraw() method before calling its other methods, even those inherited 1s. =;

    And casting doesn't actually convert anything. It simply changes the object's datatype "perception".

    For example, if you cast (PImage) over some PGraphics object, that object is still a PGraphics.
    Only its members are restrict to those belonging to PImage's class, as long as it's under the cast "effect".

  • Answer ✓

    [Q5] Both background() & set() simply copy the PImage pixels to the PGraphics, disregarding any mode effects and w/o caching the PImage in the PGraphics.

  • Answer ✓

    Now, I need to decide one over the other.

    It should mainly be based on whether the chosen datatype got all the members you need to access.

  • And casting doesn't actually convert anything. It simply changes the object's datatype "perception".

    I understand the concept. However when it comes to for example, drawing an ellipse object into the graphics, I do not need to call beginDraw(). In your A2 answer you described that we are working with a PGraphics. When I do

    draw(){ellipse,0,0,100,100);}

    I am not invoking beginDraw/endDraw. It confuses me. However I did find in the PGraphics reference that this is the option I should be using if drawing an external (alternate) image buffer and that is what I am aiming to.

    Kf

  • edited December 2016 Answer ✓

    I believe beginDraw() & endDraw() are automatically invoked before & after draw(). :ar!

  • Related to my last post, if I create a PGraphics object as a secondary buffer to store data, could I load an image into it? This is a theoretical question more than anything else. I was going to try it out except Idk how to load an image into the PGraphics object as:

    1. Loading an image requires calling loadImage() with return a PImage (there isn't a function that returns a PGraphics - no that I am aware of)
    2. Even if I load an image into a PImage object, how do I transfer the image into the PGraphics object? I guess I will need to call beginDraw()/endDraw()?

    This is a theoretical question more than anything. I am thinking I could use it to optimize some image processing code.

    Kf

  • edited December 2016 Answer ✓

    ... could I load an image into it?

    We don't load, but "stamp" a PImage onto a PGraphics.
    For that we can use: image(), set() or background().

  • @GoToLoop you say.

    BtW, there are 3rd-party libraries w/ classes which extend PImage too. For example classes Movie & Capture.

    So, Movie and Capture are third-party libraries? I thought they were made by the Processing foundation and were "official" libraries.

  • Let's just say non-bundled libraries then. :P

Sign In or Register to comment.