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

Re: [pygame] Exception in _numpysurfarray.py



Marcus von Appen wrote:
On, Fri Apr 11, 2008, Lenard Lindstrom wrote:

Lorenz Quack wrote:

[...]
The patch may have been a bit premature:
The person who initially reported this problem to me tells me that with this fix applying changes to the pixels3d array does not change the original surface. I guess that numpy.reshape() making a copy does cause problems in some cases. I'm out of ideas how to go about this...

That's peculiar.

import numpy
help(numpy.ndarray.reshape)
Help on method_descriptor:

reshape(...)
   a.reshape(d1, d2, ..., dn, order='c')

Return a new array from this one. The new array must have the same number of elements as self. Also always returns a view or raises a ValueError if
   that is impossible.


Unless I am mistaken a view is an array that references another array.

pydoc numpy.reshape:
  Help on function reshape in numpy:

  numpy.reshape = reshape(a, newshape, order='C')
    Returns an array containing the data of a, but with a new shape.
    [...]
    *Returns*:
      reshaped_array : array
          This will be a new view object if possible; otherwise, it will
          return a copy.

Attached you'll find the second try to get rid of this issue. Can you
please test it? It (once more) works well for me :-).

Regards
Marcus


Hi Marcus,

your patch didn't work for me. But creating the array in one step rather than rearranging it several times seems intriguing. I played around with it a bit and now it works for me. I don't know about that mysterious friend of mine but I'll send him the patch as well and let you know what his results are.

The only thing that is a little strange right now is that on a 32 bit surface the alpha channel ends up at index 0 with r,g,b at 1,2,3. this happens because in the get_buffer() stream the order is b,g,r,a (even though the surface.get_shifts() seems to indicate the the order is RGB). so it is kind of hard to reorder the rgb without also reversing the alpha channel.

let me know if you have any problems with the patch I attached.


yours
//Lorenz



--- _numpysurfarray.py	2008-04-11 23:15:36.000000000 +0200
+++ _numpysurfarray_patched.py	2008-04-11 23:16:48.000000000 +0200
@@ -192,7 +192,7 @@
         # RGB 
         end = None
         if pygame.get_sdl_byteorder () == pygame.LIL_ENDIAN:
-            start = 2
+            start = bpp - 1
             step = -1
         else:
             start = 0
@@ -204,15 +204,13 @@
             start = 0
             step = 1
         else:
-            start = 2
+            start = bpp - 1
             step = -1
 
-    array = numpy.frombuffer (surface.get_buffer (), numpy.uint8)
-    array.shape = surface.get_height (), surface.get_pitch ()
-    array = array[:,:surface.get_width () * bpp]
-    array = numpy.reshape (array, (surface.get_width (), surface.get_height (),
-                                   bpp))
-    array = array[:,:,start:end:step]
+    array = numpy.ndarray \
+            (shape=(surface.get_width (), surface.get_height (), bpp),
+             dtype=numpy.uint8, buffer=surface.get_buffer (),
+             offset=start, strides=(surface.get_pitch (), bpp, step))
     return array
 
 def array_alpha (surface):