Package pype :: Module spritetools
[frames] | no frames]

Source Code for Module pype.spritetools

  1  # -*- Mode: Python; tab-width: 4; py-indent-offset: 4; -*- 
  2   
  3  """Supplemental sprite functions. 
  4   
  5  These are mostly generator functions that fill sprites with 
  6  useful pixel patterns: gratings of various times, Gaussian 
  7  envelopes etc. It extends the basic functionality provided 
  8  by the sprite module and most functions work on existing 
  9  Sprite objects by modding the underlying image data. 
 10   
 11  Author -- James A. Mazer (mazerj@gmail.com) 
 12   
 13  """ 
 14   
 15  import numpy as np 
 16  import sprite 
 17   
18 -class SpritetoolsError(Exception): pass
19 20 ########################################################################## 21 # new, faster, clean support functions added 04-mar-2004 JAM .. stop 22 # using the old versions.. 23 ########################################################################## 24
25 -def unpack_rgb(color, R, G, B):
26 # 1. if color is given, assume it's a [0-1] RGB triple as list 27 # 2. if R is an array assume it's an [0-255] RGB triple 28 # 3. fallback to R, G and B as individual [0-255] RGB values 29 # inputs: [0-255] 30 # outputs: [0-1.0] 31 32 if color: 33 R, G, B = color 34 else: 35 try: 36 R, G, B = np.array(R) / 255.0 37 except TypeError: 38 pass 39 except ValueError: 40 pass 41 return R, G, B
42
43 -def g2rgb(a):
44 """Convert an [WxHx1] grayscale image into a [WxHx3] RGB array. 45 46 :param a: (array) monochrome input image 47 48 :return: (array) RGB output image 49 50 """ 51 return np.transpose(np.array([a, a, a]), axes=[1,2,0])
52
53 -def pixelize(a, rgb=None, norm=1):
54 """Convert a floating point array into an np.uint8 array. 55 56 :param a: (array) array to be converted 57 58 :param rgb: if true, then promote from 1 plane to 3 planes using g2rgb 59 60 :param norm: (boolean) if true, scale min-max into range 1-255 61 62 :return: pixelized version of input array; result is suitable for 63 assigning to <sprite>.alpha or <sprite>.array. 64 65 """ 66 if norm: 67 amin = min(ravel(a)) 68 amax = max(ravel(a)) 69 a = (1.0 + 254.0 * ((a - amin) / (amax - amin))).astype(np.uint8) 70 else: 71 a = a.astype(np.uint8) 72 if rgb is None: 73 return a 74 else: 75 return g2rgb(a)
76
77 -def genpolar(w, h=None, typecode=np.float64, degrees=False):
78 """Generate polar axes (like polar meshgrid) 79 80 :param w, h: width and height of sprite (height defaults to width) 81 82 :param typecode: output type, defaults to float64 ('d') 83 84 :param degrees: True/False 85 86 :return: (array) r and theta arrays 87 88 """ 89 x, y = sprite.genaxes(w, h, w, h) 90 r = np.hypot(x,y).astype(typecode) 91 if degrees: 92 t = (180.0 * np.arctan2(y, x) / np.pi).astype(typecode) 93 else: 94 t = np.arctan2(y, x).astype(typecode) 95 return r, t
96
97 -def gray2rgb8(g, inrange=(-1.0, 1.0)):
98 """Convert grayscale image array to 8bit integer array. 99 100 :param g: (numpy array) gray scale image array 101 102 :param inrange: (float pair) min/max values for input image 103 104 :return: (numpy array) uint8 RGB array 105 106 """ 107 108 minval, maxval = inrange 109 a = 255.0 * (g - minval) / (maxval - minval) 110 return np.transpose(np.array((a,a,a,)).astype(np.uint8), axes=[1,2,0])
111
112 -def rgb2rgb8(r, g, b, inrange=(-1.0, 1.0)):
113 """Convert rgb image data to 8bit integer array. 114 115 :param r,g,b: (numpy arrays) red, green and blue image planes 116 117 :param inrange: (float pair) min/max values for input image 118 119 :return: (numpy array) uint8 RGB array 120 121 """ 122 123 minval, maxval = inrange 124 a = np.array((r, g, b,)) 125 a = 255.0 * (a - minval) / (maxval - minval) 126 return np.transpose(a.astype(np.uint8), axes=[1,2,0])
127
128 -def singrat(s, frequency, phase_deg, ori_deg, R=1.0, G=1.0, B=1.0, 129 meanlum=0.5, moddepth=1.0, ppd=None, color=None):
130 """2D sine grating generator (odd symmetric). 131 132 *NB* Verified frequency is really cycles/sprite JM 17-sep-2006. 133 134 :param s: (Sprite) target sprite 135 136 :param frequency: frequency in cycles/sprite (or cyc/deg, if ppd 137 is given) 138 139 :param phase_deg: (degrees) (nb: 0deg phase centers the sine 140 function at sprite ctr) 141 142 :param ori_deg: (degrees) grating orientation 143 144 :param R,G,B: (either R is colortriple or R,G,B are 0-1 values) 145 146 :param ppd: (pixels/degree) if specified, then it means that freq 147 is being specified in cycles/degree 148 149 :param meanlum: mean (DC) value of grating (0-1); default is 0.5 150 151 :param moddepth: modulation depth (0-1) 152 153 :param color: RGB triple (alternative specification of color vector) 154 155 :return: nothing (works in place) 156 157 """ 158 159 if s.w != s.h: 160 raise SpritetoolsError, 'sprite must be square' 161 162 if not ppd is None: 163 # c/deg -> c/sprite 164 frequency = s.w / ppd * frequency 165 meanlum = 256.0 * meanlum 166 moddepth = 127.0 * moddepth 167 168 R, G, B = unpack_rgb(color, R, G, B) 169 r = np.hypot(s.xx/s.w, s.yy/s.h) 170 t = np.arctan2(s.yy, s.xx) 171 t = t - (np.pi * ori_deg) / 180. 172 x, y = (r * np.cos(t), r * np.sin(t)) 173 174 i = moddepth * np.sin((2.0 * np.pi * frequency * x) - 175 (np.pi * phase_deg / 180.0)) 176 s.array[::] = np.transpose((np.array((R*i,G*i,B*i)) + 177 meanlum).astype(np.uint8), 178 axes=[1,2,0])
179
180 -def cosgrat(s, frequency, phase_deg, ori_deg, R=1.0, G=1.0, B=1.0, 181 meanlum=0.5, moddepth=1.0, ppd=None, color=None):
182 """2D cosine grating generator (even symmetric). 183 184 *NB* Verified frequency is really cycles/sprite JM 17-sep-2006. 185 186 :param s: (Sprite) target sprite 187 188 :param frequency: frequency in cycles/sprite 189 190 :param phase_deg: (degrees) (nb: 0deg phase centers the cosine 191 function at sprite ctr) 192 193 :param ori_deg: (degrees) grating orientation 194 195 :param R,G,B: (either R is colortriple or R,G,B are 0-1 values) 196 197 :param ppd: (pixels/degree) if specified, then it means that freq 198 is being specified in cycles/degree 199 200 :param meanlum: mean (DC) value of grating (0-1); default is 0.5 201 202 :param moddepth: modulation depth (0-1) 203 204 :param color: RGB triple (alternative specification of color vector) 205 206 :return: nothing (works in place) 207 208 """ 209 return singrat(s, frequency, phase_deg - 90.0, ori_deg, 210 R=R, G=G, B=B, meanlum=meanlum, moddepth=moddepth, 211 ppd=ppd, color=color)
212
213 -def singrat2(s, frequency, phase_deg, ori_deg, R=1.0, G=1.0, B=1.0, 214 meanlum=0.5, moddepth=1.0, ppd=None, color=None, xcache=None):
215 """CACHING version of singrat 216 217 This is identical to singrat(), but will cache the coordinate 218 system (based on ori_deg) in a dictionary for fast retrival. This 219 can really speed things up when generating a large number of 220 gratings that differ only in phase or sf. 221 222 If you don't need caching, don't use this! 223 224 :param xcache: (dict) the actual cache 225 226 :return: (dict) updated cache 227 228 """ 229 230 if s.w != s.h: 231 raise SpritetoolsError, 'sprite must be square' 232 233 if not ppd is None: 234 # c/deg -> c/sprite 235 frequency = s.w / ppd * frequency 236 meanlum = 256.0 * meanlum 237 moddepth = 127.0 * moddepth 238 239 R, G, B = unpack_rgb(color, R, G, B) 240 241 # Generating the coordinate system is about 200ms/sprite. We can 242 # cache the orientation used for each one and speed things up 243 # considerably. Here's the full calculation: 244 if (xcache is None) or (ori_deg not in xcache): 245 r = np.hypot(s.xx/s.w, s.yy/s.h) 246 t = np.arctan2(s.yy, s.xx) 247 t = t - (np.pi * ori_deg) / 180. 248 x = r * np.cos(t) 249 if xcache is None: 250 xcache = dict() 251 xcache[ori_deg] = x 252 else: 253 x = xcache[ori_deg] 254 255 # This stuff still takes about 500ms/fullscreen sprite 256 i = moddepth * np.sin((2.0 * np.pi * frequency * x) - 257 (np.pi * phase_deg / 180.0)) 258 s.array[::] = np.transpose((np.array((R*i,G*i,B*i)) + 259 meanlum).astype(np.uint8), 260 axes=[1,2,0]) 261 return xcache
262
263 -def cosgrat2(s, frequency, phase_deg, ori_deg, R=1.0, G=1.0, B=1.0, 264 meanlum=0.5, moddepth=1.0, ppd=None, color=None, xcache=None):
265 """CACHING version of cosgrat 266 267 This is identical to cosgrat(), but will cache the coordinate 268 system (based on ori_deg) in a dictionary for fast retrival. This 269 can really speed things up when generating a large number of 270 gratings that differ only in phase or sf. 271 272 If you don't need caching, don't use this! 273 274 :param xcache: (dict) the actual cache 275 276 :return: (dict) updated cache 277 278 """ 279 280 return singrat2(s, frequency, phase_deg - 90.0, ori_deg, 281 R=R, G=G, B=B, meanlum=meanlum, moddepth=moddepth, 282 ppd=ppd, color=color)
283
284 -def polargrat(s, cfreq, rfreq, phase_deg, polarity, 285 R=1.0, G=1.0, B=1.0, logpolar=False, 286 meanlum=0.5, moddepth=1.0, ppd=None, color=None):
287 """2D polar (non-Cartesian) grating generator. 288 289 *NB* Verified frequencies are really cycles/sprite JM 17-sep-2006. 290 291 :param s: (Sprite) target sprite 292 293 :param cfreq: concentric frequency (cycles/sprite or cyc/deg - see ppd) 294 295 :param rfreq: concentric frequency (cycles/360deg) 296 297 :param phase_deg: (degrees) 298 299 :param polarity: 0 or 1 -> really just a 180 deg phase shift 300 301 :param R,G,B: (either R is colortriple or R,G,B are 0-1 values) 302 303 :param ppd: (pixels/degree); if specified, then it means that freq 304 is being specified in cycles/degree - for cfreq only 305 306 :param meanlum: mean (DC) value of grating (0-1); default is 0.5 307 308 :param moddepth: modulation depth (0-1) 309 310 :param color: RGB triple (alternative specification of color vector) 311 312 """ 313 314 if s.w != s.h: 315 raise SpritetoolsError, 'sprite must be square' 316 317 if not ppd is None: 318 # c/deg -> c/sprite 319 cfreq = s.w / ppd * cfreq 320 meanlum = 256.0 * meanlum 321 moddepth = 127.0 * moddepth 322 323 R, G, B = unpack_rgb(color, R, G, B) 324 if polarity < 0: 325 polarity = -1.0 326 else: 327 polarity = 1.0 328 x, y = (polarity * s.xx/s.w, s.yy/s.h) 329 330 if logpolar: 331 z = (np.log(np.hypot(x,y)) * cfreq) + (np.arctan2(y,x) * rfreq / 332 (2.0 * np.pi)) 333 else: 334 z = (np.hypot(y,x) * cfreq) + (np.arctan2(y,x) * rfreq / (2.0 * np.pi)) 335 i = moddepth * np.cos((2.0 * np.pi * z) - (np.pi * phase_deg / 180.0)) 336 s.array[::] = np.transpose((np.array((R*i,G*i,B*i)) + 337 meanlum).astype(np.uint8), 338 axes=[1,2,0])
339
340 -def logpolargrat(s, cfreq, rfreq, phase_deg, polarity, 341 R=1.0, G=1.0, B=1.0, 342 meanlum=0.5, moddepth=1.0, ppd=None, color=None):
343 """2D log polar (non-Cartesian) grating generator 344 345 *NB* Frequencies are in cycles/sprite or cycles/360deg 346 347 *NB* Verified frequenies are really cycles/sprite JM 17-sep-2006. 348 349 :param s: (Sprite) target sprite 350 351 :param cfreq: concentric frequency (cycles/sprite or cycles/deg see ppd) 352 353 :param rfreq: concentric frequency (cycles/360deg) 354 355 :param phase_deg: (degrees) 356 357 :param polarity: 0 or 1 -> really just a 180 deg phase shift 358 359 :param R,G,B: (either R is colortriple or R,G,B are 0-1 values) 360 361 :param ppd: (pixels/degree) if specfied, then it means that freq 362 is being specified in cycles/degree 363 364 :param meanlum: meanlum (DC) value of grating (0-1); default is 0.5 365 366 :param moddepth: modulation depth (0-1) 367 368 :param color: RGB triple (alternative specification of color vector) 369 370 :return: nothing (works in place) 371 372 """ 373 polargrat(s, cfreq, rfreq, phase_deg, polarity, 374 R=R, G=G, B=B, logpolar=1, 375 meanlum=meanlum, moddepth=moddepth, ppd=ppd)
376
377 -def hypergrat(s, freq, phase_deg, ori_deg, 378 R=1.0, G=1.0, B=1.0, 379 meanlum=0.5, moddepth=1.0, ppd=None, color=None):
380 """2D hyperbolic (non-Cartesian) grating generator. 381 382 *NB* frequencies are in cycles/sprite or cycles/360deg 383 384 *NB* verified frequencies are really cycles/sprite JM 17-sep-2006 385 386 :param s: (Sprite) target sprite 387 388 :param freq: frequency (cycles/sprite or cyc/deg - see ppd) 389 390 :param phase_deg: (degrees) 391 392 :param ori_deg: (degrees) orientation 393 394 :param R,G,B: (either R is colortriple or R,G,B are 0-1 values) 395 396 :param ppd: (pixels/deg) if specified, then it means that freq is 397 being specified in cycles/degreee 398 399 :param meanlum: mean (DC) value of grating (0-1); default is 0.5 400 401 :param moddepth: modulation depth (0-1) 402 403 :param color: RGB triple (alternative specification of color vector) 404 405 :return: nothing (works in place) 406 407 """ 408 409 if s.w != s.h: 410 raise SpritetoolsError, 'sprite must be square' 411 412 if not ppd is None: 413 # c/deg -> c/sprite 414 freq = s.w / ppd * freq 415 meanlum = 256.0 * meanlum 416 moddepth = 127.0 * moddepth 417 418 R, G, B = unpack_rgb(color, R, G, B) 419 r = np.hypot(s.xx / s.w, s.yy / s.h) 420 t = np.arctan2(s.yy, s.xx) - (np.pi * ori_deg) / 180.0 421 x, y = (r * np.cos(t), r * np.sin(t)) 422 423 z = np.sqrt(np.fabs((x * freq) ** 2 - (y * freq) ** 2)) 424 i = moddepth * np.cos((2.0 * np.pi * z) - (np.pi * phase_deg / 180.0)) 425 s.array[::] = np.transpose((np.array((R*i,G*i,B*i)) + 426 meanlum).astype(np.uint8), axes=[1,2,0])
427 428
429 -def hartley(s, kx, ky, R=1.0, G=1.0, B=1.0, 430 meanlum=0.5, moddepth=1.0, color=None):
431 """Hartley basis function generator (after Ringach et al, 1997) 432 433 :param s: (Sprite) target sprite 434 435 :param kx, ky: combind ori/sf/phase params (see paper) these are 436 basically in cycles/sprite, so the nyquist limit is size/2.. 437 438 :param R,G,B: (either R is colortriple or R,G,B are 0-1 values) 439 440 :param meanlum: mean (DC) value of grating (0-1); default is 0.5 441 442 :param moddepth: modulation depth (0-1) 443 444 :param color: RGB triple (alternative specification of color vector) 445 446 :return: nothing (works in place) 447 448 """ 449 450 if s.w != s.h: 451 raise SpritetoolsError, 'sprite must be square' 452 453 meanlum = 256.0 * meanlum 454 moddepth = 127.0 * moddepth 455 R, G, B = unpack_rgb(color, R, G, B) 456 457 M = s.w 458 l = s.xx + M/2 459 m = s.yy + M/2 460 t = 2.0 * np.pi * ((kx * l) + (ky * m)) / M 461 i = moddepth * (np.sin(t) + np.cos(t)) / np.sqrt(2.0) 462 s.array[::] = np.transpose((np.array((R*i,G*i,B*i)) + 463 meanlum).astype(np.uint8), 464 axes=[1,2,0])
465
466 -def gabor(s, frequency, phase_deg, ori_deg, sigma, 467 R=1.0, G=1.0, B=1.0, 468 meanlum=0.5, moddepth=1.0, ppd=None, color=None):
469 """2D gabor generator. 470 471 :param s: (Sprite) target sprite 472 473 :param frequency: frequency in cycles/sprite (or cyc/deg, if ppd 474 is given) 475 476 :param phase_deg: (degrees) (nb: 0deg phase centers the sine 477 function at sprite ctr) 478 479 :param ori_deg: (degrees) grating orientation 480 481 :param sigma: (pixels) envelope width -- sprite should be at 482 least 6*sigma by 6*sigma in width and height 483 484 :param R,G,B: (either R is colortriple or R,G,B are 0-1 values) 485 486 :param ppd: (pixels/degree) if specified, then it means that freq 487 is being specified in cycles/degree 488 489 :param meanlum: mean (DC) value of grating (0-1); default is 0.5 490 491 :param moddepth: modulation depth (0-1) 492 493 :param color: RGB triple (alternative specification of color vector) 494 495 :return: nothing (works in place) 496 497 """ 498 499 if s.w != s.h: 500 raise SpritetoolsError, 'sprite must be square' 501 502 if not ppd is None: 503 # c/deg -> c/sprite 504 frequency = frequency * s.w / ppd 505 meanlum = 256.0 * meanlum 506 moddepth = 127.0 * moddepth 507 508 R, G, B = unpack_rgb(color, R, G, B) 509 510 gamma = 1.0 511 sf = frequency / s.w 512 lambda_ = 1.0 / sf 513 theta = np.pi * ori_deg / 180.0 514 phi = np.pi * phase_deg / 180.0 515 516 x = (s.xx * np.cos(theta)) + (s.yy * np.sin(theta)) 517 y = (-s.xx * np.sin(theta)) + (s.yy * np.cos(theta)) 518 g = np.exp(-((x**2) + ((gamma**2) * y**2))/(2 * (sigma**2))) * \ 519 np.cos((2.0 * np.pi * x / lambda_) - phi) 520 i = moddepth * g 521 s.array[::] = np.transpose((np.array((R*i,G*i,B*i)) + 522 meanlum).astype(np.uint8), 523 axes=[1,2,0])
524 525
526 -def uniformnoise(s, binary=False, 527 R=1.0, G=1.0, B=1.0, meanlum=0.5, moddepth=1.0, color=None):
528 """Fill sprite with uniform white noise 529 530 :param s: (Sprite) target sprite 531 532 :param binary: (boolean) binary noise? (default=False) 533 534 :param R,G,B: (either R is colortriple or R,G,B are 0-1 values) 535 536 :param meanlum: mean (DC) value of grating (0-1); default is 0.5 537 538 :param moddepth: modulation depth (0-1) 539 540 :param color: RGB triple (alternative specification of color vector) 541 542 :return: nothing (works in place) 543 544 """ 545 546 R, G, B = unpack_rgb(color, R, G, B) 547 lmin = meanlum - (modepth/2.0) 548 lmax = meanlum + (modepth/2.0) 549 i = np.random.uniform(lmin, lmax, size=(s.w, s.h)) 550 if binary: 551 i = np.where(np.less(i, meanlum), lmin, lmax) 552 i = (255.0 * i).astype(np.uint8) 553 s.array[::] = np.transpose(np.array((R*i,G*i,B*i)), axes=[1,2,0])
554
555 -def gaussiannoise(s, R=1.0, G=1.0, B=1.0, meanlum=0.5, stddev=1.0, color=None):
556 """Fill sprite with Gaussian white noise 557 558 :param s: (Sprite) target sprite 559 560 :param R,G,B: (either R is colortriple or R,G,B are 0-1 values) 561 562 :param meanlum: mean (DC) value of grating (0-1); default is 0.5 563 564 :param stddev: std of gaussian distribution (0-1) 565 566 :param color: RGB triple (alternative specification of color vector) 567 568 :return: nothing (works in place) 569 570 """ 571 572 573 R, G, B = unpack_rgb(color, R, G, B) 574 i = np.random.normal(meanlum, stddev, size=(s.w, s.h)) 575 i = (255.0 * i).astype(np.uint8) 576 s.array[::] = np.transpose(np.array((R*i,G*i,B*i)), axes=[1,2,0])
577 578
579 -def alphabar(s, bw, bh, ori_deg, R=1.0, G=1.0, B=1.0):
580 """Generate a bar into existing sprite using the alpha channel. 581 582 This fills the sprite with 'color' and then puts a [bw x bh] transparent 583 bar of the specified orientation in the alpha channel. 584 585 :param s: Sprite() 586 587 :param bw,bh: (pixels) bar width and height 588 589 :param ori_deg: (degrees) bar orientation 590 591 :param R,G,B: (either R is colortriple or R,G,B are 0-1 values) 592 593 :return: nothing (works in place) 594 595 """ 596 R, G, B = (np.array(unpack_rgb(None, R, G, B)) * 255.0).astype(np.int) 597 r, t = genpolar(s.w, s.h, degrees=True) 598 t += ori_deg 599 x = r * np.cos(t) 600 y = r * np.sin(t) 601 s.fill((R,G,B)) 602 mask = np.where(np.less(abs(x), (bw/2.0)) * np.less(np.abs(y), (bh/2.0)), 603 255, 0) 604 s.alpha[::] = mask[::].astype(np.uint8)
605
606 -def alpha_gaussian(s, xsigma, ysigma=None, ori_deg=0.0):
607 """Generate symmetric and asymmetric Gaussian envelopes 608 into the alpha channel. 609 610 *NB* alpha's have peak value of fully visible (255), low end 611 depends on sigma 612 613 :param s: (Sprite) 614 615 :param xsigma: (pixels) standard dev (think of this as the 616 Gaussian's generated with ori=0 and then rotated) 617 618 :param ysigma: (pixels) if None, then use xsigma (symmatric) 619 620 :param ori_deg: (degrees) orientation of Gaussian 621 622 :return: nothing (works in place) 623 624 """ 625 if ysigma is None: 626 ysigma = xsigma 627 r = np.hypot(s.xx, s.yy) 628 t = np.arctan2(s.yy, s.xx) - (np.pi * ori_deg) / 180.0 629 x, y = (r * np.cos(t), r * np.sin(t)) 630 i = 255.0 * np.exp(-(x**2) / (2*xsigma**2)) * np.exp(-(y**2) / (2*ysigma**2)) 631 s.alpha[::] = i[::].astype(np.uint8)
632 633 # Thu Jun 20 13:49:46 2013 mazer -- for backward compatibility 634 # alpha_gaussian replaces all of these function with the same 635 # calling sequence... 636 from pypeerrors import obsolete_fn 637 alphaGaussian = alpha_gaussian 638 alphaGaussian2 = obsolete_fn 639 alphaGaussian2 = obsolete_fn 640 gaussianEnvelope = obsolete_fn 641 642
643 -def benchmark(fb):
644 import time 645 from sprite import Sprite 646 s = Sprite(250, 250, 0, 0, fb=fb, on=1) 647 s2 = Sprite(250, 250, 0, 0, fb=fb, on=1) 648 nmax = 100 649 650 t0 = time.time() 651 for n in range(nmax): 652 singrat(s, 10, 0.0, n, R=1.0, G=1.0, B=1.0, 653 meanlum=0.5, moddepth=1.0) 654 s.blit(flip=1) 655 time.time() 656 print 'all', float(nmax) / (time.time() - t0), 'fps' 657 658 t0 = time.time() 659 for n in range(nmax): 660 singrat(s, 10, 0.0, n, R=1.0, G=1.0, B=1.0, 661 meanlum=0.5, moddepth=1.0) 662 time.time() 663 print 'compute only', float(nmax) / (time.time() - t0), 'fps' 664 665 s2 = Sprite(250, 250, 0, 0, fb=fb, on=1) 666 singrat(s2, 10, 0.0, 0, R=1.0, G=1.0, B=1.0, 667 meanlum=0.5, moddepth=1.0) 668 foo = s2.array[::] 669 bar = s2.array[::] 670 t0 = time.time() 671 for n in range(nmax): 672 foo[::] = bar[::] 673 s.blit(flip=1) 674 time.time() 675 print 'copy+blit', float(nmax) / (time.time() - t0), 'fps' 676 677 t0 = time.time() 678 for n in range(nmax): 679 s.blit(flip=1) 680 time.time() 681 print 'blit only', float(nmax) / (time.time() - t0), 'fps'
682 683 684 685 if __name__ == '__main__': 686 sys.stderr.write('%s should never be loaded as main.\n' % __file__) 687 sys.exit(1) 688