shades.canvas
canvas
contains functions/classes relating to Shades' canvas object
1""" 2canvas 3 4contains functions/classes relating to Shades' canvas object 5""" 6from random import randint, shuffle 7from typing import List, Callable 8 9import numpy as np 10 11from PIL import Image 12 13from .utils import color_clamp 14 15 16def Canvas( 17 height: int = 700, 18 width: int = 700, 19 color: List[int] = (240, 240, 240), 20 color_mode: str = 'RGB', 21 ) -> Image: 22 """ 23 Returns an blank image to draw on. 24 A function due to PIL library restrictions 25 Although in effect used as class so follows naming conventions 26 for color_mode 'RGB' and 'HSB' supported 27 ('RGBA' and 'HSBA' accepted, but may produce unexpected results) 28 """ 29 image = Image.new(color_mode, (int(width), int(height)), 30 color_clamp(color)) 31 # adding methods or state is pretty restricted by PIL design 32 # but a couple of QOL object variables 33 image.x_center = int(image.width/2) 34 image.y_center = int(image.height/2) 35 image.center = (image.x_center, image.y_center) 36 image.random_point = lambda: ( 37 randint(0, image.width), randint(0, image.height) 38 ) 39 return image 40 41 42def pixel_sort(canvas: Image, key: Callable = sum, interval: int = None) -> Image: 43 """ 44 Returns a color sorted version of canvas. 45 Accepts a custom function for sorting color tuples in key 46 """ 47 if interval is None: 48 interval = canvas.height * canvas.width 49 canvas_array = np.array(canvas) 50 pixels = canvas_array.reshape( 51 canvas.width * canvas.height, 52 len(canvas_array[0][0]) 53 ) 54 splits = int(len(pixels) / interval) 55 intervals = np.array_split(pixels, splits) 56 intervals = np.array([sorted(i, key=key) for i in intervals]) 57 pixels = intervals.reshape( 58 canvas.height, 59 canvas.width, 60 len(canvas_array[0][0]), 61 ) 62 return Image.fromarray(pixels) 63 64 65def grid_shuffle(canvas: Image, x_grids: int, y_grids: int): 66 """ 67 Returns and image, with grid sections shuffled 68 """ 69 # first off, we need to find some basics like the grid size 70 x_size = int(canvas.width / x_grids) 71 y_size = int(canvas.height / y_grids) 72 # and maybe let's make a list of all the grid corners? 73 corners = [] 74 for x_coord in range(0, canvas.width - x_size + 1, x_size): 75 for y_coord in range(0, canvas.height - y_size + 1, y_size): 76 corners.append((x_coord, y_coord)) 77 # now shuffle 78 shuffle(corners) 79 # now iterate through in pairs swapping pixels 80 # at the moment the below will error if there's an odd number 81 for i in range(0, len(corners), 2): 82 corner_a = corners[i] 83 try: 84 corner_b = corners[i+1] 85 except IndexError: 86 corner_b = corners[0] 87 88 for x_coord in range(x_size): 89 for y_coord in range(y_size): 90 a_coords = (corner_a[0] + x_coord, corner_a[1] + y_coord) 91 b_coords = (corner_b[0] + x_coord, corner_b[1] + y_coord) 92 # now swap the pixels 93 a_val = canvas.getpixel(a_coords) 94 canvas.putpixel(a_coords, canvas.getpixel(b_coords)) 95 canvas.putpixel(b_coords, a_val) 96 97 return canvas
def
Canvas( height: int = 700, width: int = 700, color: List[int] = (240, 240, 240), color_mode: str = 'RGB') -> <module 'PIL.Image' from '/usr/lib/python3/dist-packages/PIL/Image.py'>:
17def Canvas( 18 height: int = 700, 19 width: int = 700, 20 color: List[int] = (240, 240, 240), 21 color_mode: str = 'RGB', 22 ) -> Image: 23 """ 24 Returns an blank image to draw on. 25 A function due to PIL library restrictions 26 Although in effect used as class so follows naming conventions 27 for color_mode 'RGB' and 'HSB' supported 28 ('RGBA' and 'HSBA' accepted, but may produce unexpected results) 29 """ 30 image = Image.new(color_mode, (int(width), int(height)), 31 color_clamp(color)) 32 # adding methods or state is pretty restricted by PIL design 33 # but a couple of QOL object variables 34 image.x_center = int(image.width/2) 35 image.y_center = int(image.height/2) 36 image.center = (image.x_center, image.y_center) 37 image.random_point = lambda: ( 38 randint(0, image.width), randint(0, image.height) 39 ) 40 return image
Returns an blank image to draw on. A function due to PIL library restrictions Although in effect used as class so follows naming conventions for color_mode 'RGB' and 'HSB' supported ('RGBA' and 'HSBA' accepted, but may produce unexpected results)
def
pixel_sort( canvas: <module 'PIL.Image' from '/usr/lib/python3/dist-packages/PIL/Image.py'>, key: Callable = <built-in function sum>, interval: int = None) -> <module 'PIL.Image' from '/usr/lib/python3/dist-packages/PIL/Image.py'>:
43def pixel_sort(canvas: Image, key: Callable = sum, interval: int = None) -> Image: 44 """ 45 Returns a color sorted version of canvas. 46 Accepts a custom function for sorting color tuples in key 47 """ 48 if interval is None: 49 interval = canvas.height * canvas.width 50 canvas_array = np.array(canvas) 51 pixels = canvas_array.reshape( 52 canvas.width * canvas.height, 53 len(canvas_array[0][0]) 54 ) 55 splits = int(len(pixels) / interval) 56 intervals = np.array_split(pixels, splits) 57 intervals = np.array([sorted(i, key=key) for i in intervals]) 58 pixels = intervals.reshape( 59 canvas.height, 60 canvas.width, 61 len(canvas_array[0][0]), 62 ) 63 return Image.fromarray(pixels)
Returns a color sorted version of canvas. Accepts a custom function for sorting color tuples in key
def
grid_shuffle( canvas: <module 'PIL.Image' from '/usr/lib/python3/dist-packages/PIL/Image.py'>, x_grids: int, y_grids: int):
66def grid_shuffle(canvas: Image, x_grids: int, y_grids: int): 67 """ 68 Returns and image, with grid sections shuffled 69 """ 70 # first off, we need to find some basics like the grid size 71 x_size = int(canvas.width / x_grids) 72 y_size = int(canvas.height / y_grids) 73 # and maybe let's make a list of all the grid corners? 74 corners = [] 75 for x_coord in range(0, canvas.width - x_size + 1, x_size): 76 for y_coord in range(0, canvas.height - y_size + 1, y_size): 77 corners.append((x_coord, y_coord)) 78 # now shuffle 79 shuffle(corners) 80 # now iterate through in pairs swapping pixels 81 # at the moment the below will error if there's an odd number 82 for i in range(0, len(corners), 2): 83 corner_a = corners[i] 84 try: 85 corner_b = corners[i+1] 86 except IndexError: 87 corner_b = corners[0] 88 89 for x_coord in range(x_size): 90 for y_coord in range(y_size): 91 a_coords = (corner_a[0] + x_coord, corner_a[1] + y_coord) 92 b_coords = (corner_b[0] + x_coord, corner_b[1] + y_coord) 93 # now swap the pixels 94 a_val = canvas.getpixel(a_coords) 95 canvas.putpixel(a_coords, canvas.getpixel(b_coords)) 96 canvas.putpixel(b_coords, a_val) 97 98 return canvas
Returns and image, with grid sections shuffled