103 lines
3.2 KiB
Python
103 lines
3.2 KiB
Python
#!/usr/bin/env python
|
|
""" pg.examples.vgrade
|
|
|
|
This example demonstrates creating an image with numpy
|
|
python, and displaying that through SDL. You can look at the
|
|
method of importing numpy and pg.surfarray. This method
|
|
will fail 'gracefully' if it is not available.
|
|
I've tried mixing in a lot of comments where the code might
|
|
not be self explanatory, nonetheless it may still seem a bit
|
|
strange. Learning to use numpy for images like this takes a
|
|
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
|
|
|
|
The window will have no border decorations.
|
|
|
|
The code also demonstrates use of the timer events.
|
|
"""
|
|
|
|
|
|
import os
|
|
import pygame as pg
|
|
|
|
try:
|
|
import numpy as np
|
|
import numpy.random as np_random
|
|
except ImportError:
|
|
raise SystemExit("This example requires numpy and the pygame surfarray module")
|
|
|
|
timer = 0
|
|
|
|
|
|
def stopwatch(message=None):
|
|
"simple routine to time python code"
|
|
global timer
|
|
if not message:
|
|
timer = pg.time.get_ticks()
|
|
return
|
|
now = pg.time.get_ticks()
|
|
runtime = (now - timer) / 1000.0 + 0.001
|
|
print("%s %s %s" % (message, runtime, ("seconds\t(%.2ffps)" % (1.0 / runtime))))
|
|
timer = now
|
|
|
|
|
|
def VertGradientColumn(surf, topcolor, bottomcolor):
|
|
"creates a new 3d vertical gradient array"
|
|
topcolor = np.array(topcolor, copy=False)
|
|
bottomcolor = np.array(bottomcolor, copy=False)
|
|
diff = bottomcolor - topcolor
|
|
width, height = surf.get_size()
|
|
# create array from 0.0 to 1.0 triplets
|
|
column = np.arange(height, dtype="float") / height
|
|
column = np.repeat(column[:, np.newaxis], [3], 1)
|
|
# create a single column of gradient
|
|
column = topcolor + (diff * column).astype("int")
|
|
# make the column a 3d image column by adding X
|
|
column = column.astype("uint8")[np.newaxis, :, :]
|
|
# 3d array into 2d array
|
|
return pg.surfarray.map_array(surf, column)
|
|
|
|
|
|
def DisplayGradient(surf):
|
|
"choose random colors and show them"
|
|
stopwatch()
|
|
colors = np_random.randint(0, 255, (2, 3))
|
|
column = VertGradientColumn(surf, colors[0], colors[1])
|
|
pg.surfarray.blit_array(surf, column)
|
|
pg.display.flip()
|
|
stopwatch("Gradient:")
|
|
|
|
|
|
def main():
|
|
pg.init()
|
|
pg.mixer.quit() # remove ALSA underflow messages for Debian squeeze
|
|
size = 600, 400
|
|
os.environ["SDL_VIDEO_CENTERED"] = "1"
|
|
screen = pg.display.set_mode(size, pg.NOFRAME, 0)
|
|
|
|
pg.event.set_blocked(pg.MOUSEMOTION) # keep our queue cleaner
|
|
pg.time.set_timer(pg.USEREVENT, 500)
|
|
|
|
while 1:
|
|
event = pg.event.wait()
|
|
if event.type in (pg.QUIT, pg.KEYDOWN, pg.MOUSEBUTTONDOWN):
|
|
break
|
|
elif event.type == pg.USEREVENT:
|
|
DisplayGradient(screen)
|
|
|
|
pg.quit()
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|