1#!/usr/bin/env python
2""" pg.examples.vgrade
3
4This example demonstrates creating an image with numpy
5python, and displaying that through SDL. You can look at the
6method of importing numpy and pg.surfarray. This method
7will fail 'gracefully' if it is not available.
8I've tried mixing in a lot of comments where the code might
9not be self explanatory, nonetheless it may still seem a bit
10strange. Learning to use numpy for images like this takes a
11bit of learning, but the payoff is extremely fast image
12manipulation in python.
13
14For Pygame 1.9.2 and up, this example also showcases a new feature
15of surfarray.blit_surface: array broadcasting. If a source array
16has either a width or height of 1, the array is repeatedly blitted
17to the surface along that dimension to fill the surface. In fact,
18a (1, 1) or (1, 1, 3) array results in a simple surface color fill.
19
20Just so you know how this breaks down. For each sampling of
21time, 30% goes to each creating the gradient and blitting the
22array. The final 40% goes to flipping/updating the display surface
23
24The window will have no border decorations.
25
26The code also demonstrates use of the timer events.
27"""
28
29
30import os
31import pygame as pg
32
33try:
34    import numpy as np
35    import numpy.random as np_random
36except ImportError:
37    raise SystemExit("This example requires numpy and the pygame surfarray module")
38
39timer = 0
40
41
42def stopwatch(message=None):
43    "simple routine to time python code"
44    global timer
45    if not message:
46        timer = pg.time.get_ticks()
47        return
48    now = pg.time.get_ticks()
49    runtime = (now - timer) / 1000.0 + 0.001
50    print("%s %s %s" % (message, runtime, ("seconds\t(%.2ffps)" % (1.0 / runtime))))
51    timer = now
52
53
54def VertGradientColumn(surf, topcolor, bottomcolor):
55    "creates a new 3d vertical gradient array"
56    topcolor = np.array(topcolor, copy=False)
57    bottomcolor = np.array(bottomcolor, copy=False)
58    diff = bottomcolor - topcolor
59    width, height = surf.get_size()
60    # create array from 0.0 to 1.0 triplets
61    column = np.arange(height, dtype="float") / height
62    column = np.repeat(column[:, np.newaxis], [3], 1)
63    # create a single column of gradient
64    column = topcolor + (diff * column).astype("int")
65    # make the column a 3d image column by adding X
66    column = column.astype("uint8")[np.newaxis, :, :]
67    # 3d array into 2d array
68    return pg.surfarray.map_array(surf, column)
69
70
71def DisplayGradient(surf):
72    "choose random colors and show them"
73    stopwatch()
74    colors = np_random.randint(0, 255, (2, 3))
75    column = VertGradientColumn(surf, colors[0], colors[1])
76    pg.surfarray.blit_array(surf, column)
77    pg.display.flip()
78    stopwatch("Gradient:")
79
80
81def main():
82    pg.init()
83    pg.mixer.quit()  # remove ALSA underflow messages for Debian squeeze
84    size = 600, 400
85    os.environ["SDL_VIDEO_CENTERED"] = "1"
86    screen = pg.display.set_mode(size, pg.NOFRAME, 0)
87
88    pg.event.set_blocked(pg.MOUSEMOTION)  # keep our queue cleaner
89    pg.time.set_timer(pg.USEREVENT, 500)
90
91    while 1:
92        event = pg.event.wait()
93        if event.type in (pg.QUIT, pg.KEYDOWN, pg.MOUSEBUTTONDOWN):
94            break
95        elif event.type == pg.USEREVENT:
96            DisplayGradient(screen)
97
98    pg.quit()
99
100
101if __name__ == "__main__":
102    main()
103