Bug 168 : improve PImage subclassing
Last modified: 2005-10-22 22:22




Status:
RESOLVED
Resolution:
WONTFIX -
Priority:
P3
Severity:
normal

 

Reporter:
22samurai
Assigned To:
fry

Attachment Type Created Size Actions

Description:   Opened: 2005-10-08 12:42
Subclassing the PImage class should be more intuitive.

If a user wants to subclass the PImage class to extend its functionality,
he runs into the problem of initialization of the Subclass, along with
loading images from files.

As it stands now, to load an image into a subclass of PImage, the user has
to create both an instance of PImage and the subclass, use loadImage (which
returns a PImage) to load data into the PImage, and then copy the PImage
data and other field data into the subclass by him/herself.

It is possible, but rather circuitous. Ideally, the loadImage() method
should be in PImage, so that image-loading functionality gets inherited by
any subclass.

There are also problems to the circuitous approach explained above. A
complete list of fields is not in the documentation. The user must either
find the PImage source code or disassemble it in order to discover all the
fields. After that, there is still no easy way to copy the data without
doing it manually.

If there is a simpler way, it is not explained clearly. The source code
for PImage makes mention of init() and clone(), but it is not clear (in the
source code or the documentation) how to use these methods in intializing a
subclass.
Additional Comment #1 From fry 2005-10-08 12:51
rather than speaking in the abstract case, what are you trying to do that you can't?

image i/o isn't in PImage because the applet object has to handle any i/o. this is simply the
case for how applets work.

it's weird having the image parsing in PApplet too, and it might make sense to move it, but
i haven't determined if there's a great advantage one way or another. i have a note in my
todo list about figuring this out,

there is no need to "disassemble" the code, you're being a bit dramatic. the source is on this
site: http://dev.processing.org/source/
Additional Comment #2 From 22samurai 2005-10-10 19:47

> rather than speaking in the abstract case, what are you trying to
do that you can't?

We wanted to be able to create a subclass of PImage (call it XImage for
short) and load an image into it with the least amount of difficulty. I
described one way of doing it (make both a PImage and XImage instance, use
loadImage() to load the graphic into the PImage, and transfer the data to
XImage using a deep copy method ), but it seems to me that there should be
an easier way to perform that task.

> there is no need to "disassemble" the code, you're being a bit dramatic.
the source is on this
> site: http://dev.processing.org/source/

I did say "either find the PImage source code <i>or</i> disassemble it".
Of course that's a last resort - I only mentioned disassembly because it
was one method of achieving finding the info we needed.

Making accurate initialization and deep copy methods to fill in the fields
derived from PImage in our subclass, XImage involved finding the
undocumented public fields of PImage.
Additional Comment #3 From fry 2005-10-11 00:32
i understand that you want to create a subclass, but what does the subclass do that you
cannot now? is it opening image file formats that we don't currently support? or are you just
not understanding what PImage does? do you mean that you want to improve loadImage()
to extend it in some way? do you have an example?
Additional Comment #4 From 22samurai 2005-10-22 21:15
> i understand that you want to create a subclass, but what does the
subclass do that you
> cannot now?

This was originally an assignment that asked us to extend PImage to include
a new type of displaying the PImage, called "mosaic," which averages the
pixels in an NxN block. I realize that another possible way to do this
would be to create another filter effect, or even use another method not
directly connected to PImage through subclassing. However, doing this
exercise made me realize that any class that extends PImage has to perform
a cumbersome deep copy of the contents of another. PImage. The deep copy
is necessary because loadImage only returns a PImage, and since loadImage
is not in the class PImage, the loadImage call cannot be accessed by the
subclasses.

ex:
//XImage is a subclass of PImage. (class XImage extends PImage)

PImage image1;
XImage image2;

//the goal is to load a JPG into XImage.
//Since we can't do this directly, we must do this in a roundabout way.
//the only way to load an image is through PImage loadImage(filename) .

image1= loadImage("test.jpg");
//ideally, this kind of code would be best:
image2= new XImage(image1);
//in order to do this, in the constructor, you must know all the fields of
PImage. //Some of these fields are not in the documentation, but only in
the source.

//even more ideally, it would be nice to be able to say:
image2.loadImage("test".jpg);
//since loadImage is a part of PImage, it gets inherited by all its subclasses.
//no deep copying is necessary.


I hope these snippets of code help make this more concrete.

>is it opening image file formats that we don't currently support?

We were loading a simple .jpg, nothing strange about that.

> or are you just not understanding what PImage does?
I believe I have an understanding of what it does, but not a very good
understanding of how to get a copy of its image data into another class easily.

I hope this clarifies what I'm getting at... If anyone wants to extend
PImage for whatever reason, loading images into the extension of PImage is
difficult and time-consuming.

Thanks for your time,
-22
Additional Comment #5 From fry 2005-10-22 22:09
that's a little clearer.

however, why not just use image.pixels directly? there's no need to do this "deep copy", you
can just mess with the pixels[] array of the image.
Additional Comment #6 From 22samurai 2005-10-22 22:13

> however, why not just use image.pixels directly? there's no need to do
this "deep copy", you
> can just mess with the pixels[] array of the image.

Using the pixels[] array is finefor most things. In the specific case of a
subclass of PImage, how does that pixels[] array get defined? How can one
easily get image data into a subclass of PImage?

Additional Comment #7 From fry 2005-10-22 22:22
how about not using a subclass? PImage is a container of pixels that has been obtained from
loadImage(). that's all. your issue seems to be more semantic than anything else. you're
stuck on wanting to use a subclass for operations on the image, but that's not how the api is
put together. use a class that has a PImage object. or make something called XImage that
simply takes a PImage as a constructor, and says:

public XImage(PImage orig) {
pixels = orig.pixels;
}

this is not a "deep copy" and will allow you do do the sort of things you seem to want to do
with zero overhead.

at any rate, it's not something that will change anytime before at least 1.0, so i'm closing
the bug.