subpixelsurface.py 3.34 KB
 Nelso Jost committed Mar 09, 2016 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 ``````# font: http://www.pygame.org/project-Sub-pixel+surface-413-.html import pygame from pygame.locals import * from math import floor # Try to import Numpy, or Numeric try: import numpy as Numeric BYTE = "u1" DWORD = "u4" except ImportError: try: import Numeric except ImportError as e: print("Requires NumPy or Numeric!") raise e BYTE = Numeric.UnsignedInt8 DWORD = Numeric.Int32 class SubPixelSurface(object): def __init__(self, surface, x_level=3, y_level=None): """Creates a sub pixel surface object. surface -- A PyGame surface x_level -- Number of sub-pixel levels in x y_level -- Number of sub-pixel levels in y (same as x if omited) """ self.x_level = x_level self.y_level = y_level or x_level w, h = surface.get_size() ow, oh = w, h w += 2 h += 2 surf_array_rgb = Numeric.zeros((w, h, 3), BYTE) surf_array_rgb[1:ow+1:, 1:oh+1:, ::] = pygame.surfarray.array3d(surface) surf_array_a = Numeric.zeros((w, h), BYTE) surf_array_a[1:ow+1:, 1:oh+1:] = pygame.surfarray.array_alpha(surface) surf_array_rgb[0,::] = surf_array_rgb[1,::] surf_array_rgb[::,0] = surf_array_rgb[::,1] surf_array_rgb[w-1,::] = surf_array_rgb[w-2,::] surf_array_rgb[::,h-1] = surf_array_rgb[::,h-2] s = Numeric.zeros(surf_array_rgb.shape[:2]+(4,), DWORD) s[::-1, ::, :3] = surf_array_rgb s[::-1, ::, 3] = surf_array_a x_steps = [float(n) / self.x_level for n in range(self.x_level)] y_steps = [float(n) / self.y_level for n in range(self.y_level)] self.surfaces = [] for frac_y in y_steps: row = [] self.surfaces.append(row) for frac_x in x_steps: row.append( SubPixelSurface._generate(s, frac_x, frac_y) ) @staticmethod def _generate(s, frac_x, frac_y): frac_x, frac_y = frac_y, frac_x frac_x = 1. - frac_x sa = int( (1.-frac_x) * (1.-frac_y) * 255. ) sb = int( (1.-frac_x) * frac_y * 255. ) sc = int( frac_x * (1.-frac_y) * 255. ) sd = int( (frac_x * frac_y) * 255. ) a = s[ :-1:, :-1:] * sa b = s[ 1::, :-1:] * sb c = s[ :-1:, 1:: ] * sc d = s[ 1::, 1:: ] * sd a += b a += c a += d a >>= 8 rgba_data = a.astype(BYTE).tostring() pygame_surface = pygame.image.fromstring(rgba_data, a.shape[:2][::-1], "RGBA") pygame_surface = pygame.transform.rotate(pygame_surface, 270) return pygame_surface def at(self, x, y): """Gets a sub-pixel surface for a given coordinate. x -- X coordinate y -- Y coordinate """ surf_x = int( (x - floor(x)) * self.x_level ) surf_y = int( (y - floor(y)) * self.y_level ) return self.surfaces[surf_y][surf_x]``````