|
| 1 | +import pygame as pg |
| 2 | +import numpy as np |
| 3 | +import pygame.camera |
| 4 | + |
| 5 | + |
| 6 | +class Matrix: |
| 7 | + def __init__(self, app, font_size=8): |
| 8 | + self.app = app |
| 9 | + self.FONT_SIZE = font_size |
| 10 | + self.SIZE = self.ROWS, self.COLS = app.HEIGHT // font_size, app.WIDTH // font_size |
| 11 | + self.katakana = np.array([chr(int('0x30a0', 16) + i) for i in range(96)] + ['' for i in range(10)]) |
| 12 | + self.font = pg.font.Font('font/ms mincho.ttf', font_size, bold=True) |
| 13 | + |
| 14 | + self.matrix = np.random.choice(self.katakana, self.SIZE) |
| 15 | + self.char_intervals = np.random.randint(25, 50, size=self.SIZE) |
| 16 | + self.cols_speed = np.random.randint(1, 500, size=self.SIZE) |
| 17 | + self.prerendered_chars = self.get_prerendered_chars() |
| 18 | + |
| 19 | + # self.image = self.get_image('img/k1.png') |
| 20 | + |
| 21 | + def get_frame(self): |
| 22 | + image = app.cam.get_image() |
| 23 | + image = pg.transform.scale(image, self.app.RES) |
| 24 | + pixel_array = pg.pixelarray.PixelArray(image) |
| 25 | + return pixel_array |
| 26 | + |
| 27 | + def get_image(self, path_to_file): |
| 28 | + image = pg.image.load(path_to_file) |
| 29 | + image = pg.transform.scale(image, self.app.RES) |
| 30 | + pixel_array = pg.pixelarray.PixelArray(image) |
| 31 | + return pixel_array |
| 32 | + |
| 33 | + def get_prerendered_chars(self): |
| 34 | + char_colors = [(0, green, 0) for green in range(256)] |
| 35 | + prerendered_chars = {} |
| 36 | + for char in self.katakana: |
| 37 | + prerendered_char = {(char, color): self.font.render(char, True, color) for color in char_colors} |
| 38 | + prerendered_chars.update(prerendered_char) |
| 39 | + return prerendered_chars |
| 40 | + |
| 41 | + def run(self): |
| 42 | + frames = pg.time.get_ticks() |
| 43 | + self.change_chars(frames) |
| 44 | + self.shift_column(frames) |
| 45 | + self.draw() |
| 46 | + |
| 47 | + def shift_column(self, frames): |
| 48 | + num_cols = np.argwhere(frames % self.cols_speed == 0) |
| 49 | + num_cols = num_cols[:, 1] |
| 50 | + num_cols = np.unique(num_cols) |
| 51 | + self.matrix[:, num_cols] = np.roll(self.matrix[:, num_cols], shift=1, axis=0) |
| 52 | + |
| 53 | + def change_chars(self, frames): |
| 54 | + mask = np.argwhere(frames % self.char_intervals == 0) |
| 55 | + new_chars = np.random.choice(self.katakana, mask.shape[0]) |
| 56 | + self.matrix[mask[:, 0], mask[:, 1]] = new_chars |
| 57 | + |
| 58 | + def draw(self): |
| 59 | + self.image = self.get_frame() |
| 60 | + for y, row in enumerate(self.matrix): |
| 61 | + for x, char in enumerate(row): |
| 62 | + if char: |
| 63 | + pos = x * self.FONT_SIZE, y * self.FONT_SIZE |
| 64 | + _, red, green, blue = pg.Color(self.image[pos]) |
| 65 | + if red and green and blue: |
| 66 | + color = (red + green + blue) // 3 |
| 67 | + color = 220 if 160 < color < 220 else color |
| 68 | + char = self.prerendered_chars[(char, (0, color, 0))] |
| 69 | + char.set_alpha(color + 60) |
| 70 | + self.app.surface.blit(char, pos) |
| 71 | + |
| 72 | + |
| 73 | +class MatrixVision: |
| 74 | + def __init__(self): |
| 75 | + self.RES = self.WIDTH, self.HEIGHT = 960, 720 |
| 76 | + pg.init() |
| 77 | + self.screen = pg.display.set_mode(self.RES) |
| 78 | + self.surface = pg.Surface(self.RES) |
| 79 | + self.clock = pg.time.Clock() |
| 80 | + self.matrix = Matrix(self) |
| 81 | + |
| 82 | + pygame.camera.init() |
| 83 | + self.cam = pygame.camera.Camera(pygame.camera.list_cameras()[0]) |
| 84 | + self.cam.start() |
| 85 | + |
| 86 | + def draw(self): |
| 87 | + self.surface.fill(pg.Color('black')) |
| 88 | + self.matrix.run() |
| 89 | + self.screen.blit(self.surface, (0, 0)) |
| 90 | + |
| 91 | + def run(self): |
| 92 | + while True: |
| 93 | + self.draw() |
| 94 | + [exit() for i in pg.event.get() if i.type == pg.QUIT] |
| 95 | + pg.display.flip() |
| 96 | + self.clock.tick(30) |
| 97 | + |
| 98 | + |
| 99 | +if __name__ == '__main__': |
| 100 | + app = MatrixVision() |
| 101 | + app.run() |
| 102 | + |
| 103 | + |
| 104 | +""" |
| 105 | +
|
| 106 | +import pygame as pg |
| 107 | +import numpy as np |
| 108 | +import pygame.camera |
| 109 | +
|
| 110 | +
|
| 111 | +class MatrixEffect: |
| 112 | + def __init__(self, vision_app, font_size=8): |
| 113 | + self.vision_app = vision_app |
| 114 | + self.FONT_SIZE = font_size |
| 115 | + self.DIMENSIONS = self.ROWS, self.COLS = vision_app.HEIGHT // font_size, vision_app.WIDTH // font_size |
| 116 | + self.katakana_symbols = np.array([chr(int('0x30a0', 16) + i) for i in range(96)] + ['' for i in range(10)]) |
| 117 | + self.font = pg.font.Font('font/ms mincho.ttf', font_size, bold=True) |
| 118 | +
|
| 119 | + # Initialize matrix with random katakana symbols |
| 120 | + self.matrix = np.random.choice(self.katakana_symbols, self.DIMENSIONS) |
| 121 | + self.char_intervals = np.random.randint(25, 50, size=self.DIMENSIONS) |
| 122 | + self.column_speeds = np.random.randint(1, 500, size=self.DIMENSIONS) |
| 123 | + self.rendered_chars_cache = self.cache_rendered_chars() |
| 124 | +
|
| 125 | + def capture_camera_frame(self): |
| 126 | + frame = self.vision_app.camera.get_image() |
| 127 | + scaled_frame = pg.transform.scale(frame, self.vision_app.RESOLUTION) |
| 128 | + return pg.pixelarray.PixelArray(scaled_frame) |
| 129 | +
|
| 130 | + def cache_rendered_chars(self): |
| 131 | + colors = [(0, green, 0) for green in range(256)] |
| 132 | + cache = {} |
| 133 | + for char in self.katakana_symbols: |
| 134 | + rendered = {(char, color): self.font.render(char, True, color) for color in colors} |
| 135 | + cache.update(rendered) |
| 136 | + return cache |
| 137 | +
|
| 138 | + def update(self): |
| 139 | + current_time = pg.time.get_ticks() |
| 140 | + self.change_symbols(current_time) |
| 141 | + self.scroll_columns(current_time) |
| 142 | + self.render() |
| 143 | +
|
| 144 | + def scroll_columns(self, current_time): |
| 145 | + columns_to_shift = np.argwhere(current_time % self.column_speeds == 0) |
| 146 | + columns_to_shift = columns_to_shift[:, 1] |
| 147 | + unique_columns = np.unique(columns_to_shift) |
| 148 | + self.matrix[:, unique_columns] = np.roll(self.matrix[:, unique_columns], shift=1, axis=0) |
| 149 | +
|
| 150 | + def change_symbols(self, current_time): |
| 151 | + positions_to_change = np.argwhere(current_time % self.char_intervals == 0) |
| 152 | + new_symbols = np.random.choice(self.katakana_symbols, positions_to_change.shape[0]) |
| 153 | + self.matrix[positions_to_change[:, 0], positions_to_change[:, 1]] = new_symbols |
| 154 | +
|
| 155 | + def render(self): |
| 156 | + frame_pixels = self.capture_camera_frame() |
| 157 | + for y, row in enumerate(self.matrix): |
| 158 | + for x, char in enumerate(row): |
| 159 | + if char: |
| 160 | + position = x * self.FONT_SIZE, y * self.FONT_SIZE |
| 161 | + _, red, green, blue = pg.Color(frame_pixels[position]) |
| 162 | + if red and green and blue: |
| 163 | + avg_color = (red + green + blue) // 3 |
| 164 | + avg_color = 220 if 160 < avg_color < 220 else avg_color |
| 165 | + char_image = self.rendered_chars_cache[(char, (0, avg_color, 0))] |
| 166 | + char_image.set_alpha(avg_color + 60) |
| 167 | + self.vision_app.surface.blit(char_image, position) |
| 168 | +
|
| 169 | +
|
| 170 | +class MatrixCameraEffect: |
| 171 | + def __init__(self): |
| 172 | + self.RESOLUTION = self.WIDTH, self.HEIGHT = 960, 720 |
| 173 | + pg.init() |
| 174 | + self.display = pg.display.set_mode(self.RESOLUTION) |
| 175 | + self.surface = pg.Surface(self.RESOLUTION) |
| 176 | + self.fps_clock = pg.time.Clock() |
| 177 | + self.matrix_effect = MatrixEffect(self) |
| 178 | +
|
| 179 | + pygame.camera.init() |
| 180 | + self.camera = pygame.camera.Camera(pygame.camera.list_cameras()[0]) |
| 181 | + self.camera.start() |
| 182 | +
|
| 183 | + def render(self): |
| 184 | + self.surface.fill(pg.Color('black')) |
| 185 | + self.matrix_effect.update() |
| 186 | + self.display.blit(self.surface, (0, 0)) |
| 187 | +
|
| 188 | + def mainloop(self): |
| 189 | + while True: |
| 190 | + self.render() |
| 191 | + [exit() for event in pg.event.get() if event.type == pg.QUIT] |
| 192 | + pg.display.flip() |
| 193 | + self.fps_clock.tick(30) |
| 194 | +
|
| 195 | +
|
| 196 | +if __name__ == '__main__': |
| 197 | + matrix_vision_app = MatrixCameraEffect() |
| 198 | + matrix_vision_app.mainloop() |
| 199 | +""" |
0 commit comments