Commits

Lenard Lindstrom committed a8b391f

add array broadcasting to surfarray.blit_surface (pixelcopy.array_to_surface). Also do small ALSA related fix to array examples

Comments (0)

Files changed (4)

examples/blit_blends.py

 #!/usr/bin/env python
 
-# fake additive blending.  Using Numeric.  it doesn't clamp.
+# fake additive blending.  Using NumPy.  it doesn't clamp.
 # press r,g,b
 
 import os, pygame
 
 def main():
     pygame.init()
+    pygame.mixer.quit() # remove ALSA underflow messages for Debian squeeze
     screen = pygame.display.set_mode((640, 480))
 
     im1= pygame.Surface(screen.get_size())

examples/vgrade.py

 bit of learning, but the payoff is extremely fast image
 manipulation in python.
 
+For Pygame 1.9.2 and up, this example also showcases a new feature
+of surfarray.blit_surface: array broadcasting. If a source array
+has either a width or height of 1, the array is repeatedly blitted
+to the surface along that dimension to fill the surface. In fact,
+a (1, 1) or (1, 1, 3) array results in a simple surface color fill.
+
 Just so you know how this breaks down. For each sampling of
 time, 30% goes to each creating the gradient and blitting the
 array. The final 40% goes to flipping/updating the display surface
 
 
 
-def VertGrad3D(surf, topcolor, bottomcolor):
+def VertGradientColumn(surf, topcolor, bottomcolor):
     "creates a new 3d vertical gradient array"
     topcolor = array(topcolor, copy=0)
     bottomcolor = array(bottomcolor, copy=0)
     # make the column a 3d image column by adding X
     column = column.astype('uint8')[newaxis,:,:]
     #3d array into 2d array
-    column = pygame.surfarray.map_array(surf, column)
-    # stretch the column into a full image
-    return resize(column, (width, height))
+    return pygame.surfarray.map_array(surf, column)
 
 
 
     "choose random colors and show them"
     stopwatch()
     colors = randint(0, 255, (2, 3))
-    grade = VertGrad3D(surf, colors[0], colors[1])
-    pygame.surfarray.blit_array(surf, grade)
+    column = VertGradientColumn(surf, colors[0], colors[1])
+    pygame.surfarray.blit_array(surf, column)
     pygame.display.flip()
     stopwatch('Gradient:')
 
 
 def main():
     pygame.init()
+    pygame.mixer.quit() # remove ALSA underflow messages for Debian squeeze
     size = 600, 400
     os.environ['SDL_VIDEO_CENTERED'] = '1'
     screen = pygame.display.set_mode(size, NOFRAME, 0)
     Rloss = format->Rloss; Gloss = format->Gloss; Bloss = format->Bloss;
     Rshift = format->Rshift; Gshift = format->Gshift; Bshift = format->Bshift;
 
+    /* Do any required broadcasting. */
+    if (sizex == 1) {
+        sizex = surf->w;
+        stridex = 0;
+    }
+    if (sizey == 1) {
+        sizey = surf->h;
+        stridey = 0;
+    }
+
     if (sizex != surf->w || sizey != surf->h) {
         Py_DECREF(cobj);
         return RAISE(PyExc_ValueError, "array must match surface dimensions");

test/pixelcopy_test.py

         target = pygame.Surface((w - 1, h), 0, 32)
         self.assertRaises(ValueError, map_array, target, source, target)
 
+    def test_array_to_surface_broadcasting(self):
+        # target surfaces
+        targets = [self._make_surface(8),
+                   self._make_surface(16),
+                   self._make_surface(16, srcalpha=True),
+                   self._make_surface(24),
+                   self._make_surface(32),
+                   self._make_surface(32, srcalpha=True),
+                   ]
+        
+        w, h = self.surf_size
+
+        # broadcast column
+        column = pygame.Surface((1, h), 0, 32)
+        for target in targets:
+            source = pygame.Surface((1, h), 0, target)
+            for y in range(h):
+                source.set_at((0, y),
+                              pygame.Color(y + 1, y + h + 1, y + 2 * h + 1))
+            pygame.pixelcopy.surface_to_array(column.get_view('2'), source)
+            pygame.pixelcopy.array_to_surface(target, column.get_view('2'))
+            for x in range(w):
+                for y in range(h):
+                    self.assertEqual(target.get_at_mapped((x, y)),
+                                     column.get_at_mapped((0, y)))
+
+        # broadcast row
+        row = pygame.Surface((w, 1), 0, 32)
+        for target in targets:
+            source = pygame.Surface((w, 1), 0, target)
+            for x in range(w):
+                source.set_at((x, 0),
+                              pygame.Color(x + 1, x + w + 1, x + 2 * w + 1))
+            pygame.pixelcopy.surface_to_array(row.get_view('2'), source)
+            pygame.pixelcopy.array_to_surface(target, row.get_view('2'))
+            for x in range(w):
+                for y in range(h):
+                    self.assertEqual(target.get_at_mapped((x, y)),
+                                     row.get_at_mapped((x, 0)))
+
+        # broadcast pixel
+        pixel = pygame.Surface((1, 1), 0, 32)
+        for target in targets:
+            source = pygame.Surface((1, 1), 0, target)
+            source.set_at((0, 0), pygame.Color(13, 47, 101))
+            pygame.pixelcopy.surface_to_array(pixel.get_view('2'), source)
+            pygame.pixelcopy.array_to_surface(target, pixel.get_view('2'))
+            p = pixel.get_at_mapped((0, 0))
+            for x in range(w):
+                for y in range(h):
+                     self.assertEqual(target.get_at_mapped((x, y)), p)
+
+            
+
     def todo_test_array_to_surface(self):
         # target surfaces
         targets = [_make_surface(8),