[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

Re: [pygame] PixelArray question



On, Thu Aug 23, 2007, Brian Fisher wrote:

> On 8/23/07, Marcus von Appen <mva@xxxxxxxxxxxx> wrote:
> > On, Thu Aug 23, 2007, Brian Fisher wrote:
> > > On 8/22/07, Marcus von Appen <mva@xxxxxxxxxxxx> wrote:
> > No - separate purposes are best dealt with in separate, non-interfering
> > cases. As you clearly state later on in your mail, PixelArray serves a
> > complete own need with a completely own (currently only a minimum)
> > function set.
> >
> Sure, I don't disagree with the principle really.. it's a good
> principle. The problem I suppose is how you (and whether you) define
> "seperate purposes". For instance, you could say blitting to a surface
> is a "seperate purpose" than having one, in which case you wouldn't
> make the surface have a blit function (some graphics api's are in fact
> that way). So that principle in and of itself isn't sufficient to have
> a meaningful discussion of the best way to structure an api (because 2
> people could easily apply the same principle and get dramatically
> different results)

Okay, I agree with you that based on the point of view you can easily 
start nit-picking about what is a different purpose.

> > My short- to midterm goals are full mapping support (array[x1:x2, y1:y2]
> > ...), maybe the one or other fast manipulation function and whatever
> > else might fit. Putting all this functionality directly into the Surface
> > does not seem appropriate to me.
> >
> Does full mapping support mean that:
> 
> PixelArray[10:20][10:20]
> would give you a new 10 x 10 PixelArray that is a subset of the
> original, or does it mean more than that?

Your example will not work, because you'd receive a IndexError. What you
tried is to slice a 2D array twice. To slice the y offsets (rows),
you'll need the mapping, or a 1D array (a single column of the PixelArray).

Let's assume you create a PixelArray of a 20x50 surface.

      array = PixelArray (surface) 

will create a 20x50 PixelArray.

     array[10:20]

 will give you a 10x50  PixelArray of the original one, starting at x
 offset 10 and reaching to x offset 20 (the columns).

     array[10:20][10:20]

in turn thus will cause an IndexError, because you try get the 10th to
20th column of a 10-column array.

     array[10:20, 10:20]

will give you a 10x10 PixelArray, starting at x offset 10 and y offset
10 and reaching to the resp. x and y offsets 20.
In terms of Subsurfaces you'd have done something like

     Surface.subsurface ((10, 10, 10, 10))

> So what's fast manipulation function? Does that mean like inplace ops?
> Numeric style arithmetic magic?

Both. I hope to be able to realize some reasonable fast methods,
e.g. fast pixel transformations using comparision arguments, some basic
arithmetic functions, cropping and tiling, which return a PixelArray
based on a new surface, and whatever else might pop up in someone's mind
being realizable.

> 
> 
> 
> > [...PixelArray might just be redundant...]
> > > ...however keeping PixelArray as a seperate object but hiding it as an
> > > "interface" would still serve the same goals
> >
> > How would the interface look like in your opinion?
> >
> Basically it would be that you would provide buffer access operations
> on the surface, which would return a PixelArray object in the case of
> slicing.
> 
> So basically this:
>         sf = pygame.Surface ((10, 20))
>         sf.fill ((0, 0, 0))
>         ar = pygame.PixelArray (sf)
> 
>         ar2 = ar[0]
> 
> would become this:
>         sf = pygame.Surface ((10, 20))
>         sf.fill ((0, 0, 0))
>         ar2 = sf[0]
> 
> and would be functionally identical in terms of the behavior of sf & ar2
> Another way to think of it would be that buffer access on the surface
> would construct a PixelArray, and you wouldn't have to bother with the
> PixelArray constructor.

Personally I'd (especially if I'd be new to pygame) expect the latter to
return a Surface of size 1x20, not a PixelArray. So in my recognition
it'd serve a different purpose (being subjective of course).
 
> The advantages as I see it are:
> 1. you type less when you know how to do stuff

p.i.l(file) also would let you type less, when you know how to do stuff,
it does not make it more clear, however, especially for newcomers. p.i.l
means pygame.image.load() by the way ;-).

> 2. If you construct a PixelArray from a surface, it's not clear at all
> that it's data and functionality are intertwined with the Surface's
> content. However if you get a PixelArray through buffer/slicing
> access, It is fairly clear that ar2 is actually meaningfully
> intertwined with sf's data (because you got it as being an element of
> the surface)

That applies to a lot of problems, libraries, classes, etc.. The
surfarray module suffers from them as well. Not to mention python's
buffer() function, which either uses a copy or direct access of an
object's data stream. Documentation is the key to use here.

> 3. It's kind of what someone completely fresh to the problem would
> expect to be able to

I gave you a counter-example above. It's subjective (hello purpose ;-).
 
> The possible disadvantages that I see are:
> 1. It's kind of what someone completely fresh to the problem would
> expect to be able to... but it may not be signficantly differently
> from what they'd expect to be able to do in?

No idea, what you mean here.

> 2. There may be some design and implementation issues with it that
> someone who actually wrote PixelArray could see... ?

See the purpose, user expectation and recognition discussion we had so
far, when it comes to design. One big implementation issue might be the
buffer interface and locking we need for it. As it is uncertain at which
time the requester of the buffer does not need it anymore, we have to
rely on the user's explicit unlock (by using del array or in your
example a call to sf.unlock():

        sf = pygame.Surface ((10, 20))
        sf.fill ((0, 0, 0))
        buffer_request (sf)
        sf.unlock()

Looks a bit silly to me - and I would not expect that I have to do it :-).

Regards
Marcus

Attachment: pgparIpO8FHoM.pgp
Description: PGP signature