hero.py
2.0 kB · python · 80 lines
1import math23import lib # noqa: F40145import numpy as np6from PIL import Image7from mrlypy.core.colors import black, gradient, ink, white8from mrlypy.core.enums import Mode9from mrlypy.core.state import seed10from mrlypy.six import FILL, GRID, VOID11from mrlypy.six.designs import carpet_cut12from mrlypy.six.renderer import draw1314from lib.canvas import H3, quantize15from lib.paths import HERO, ensure, show1617NUMBER = 518LEVEL = 219MARGIN = 020WIDTH = 192021ASPECT = 16 / 922SEED = 2623STEPS = 24024COLORS = 25625HUES = ["red", "orange", "yellow", "green", "mint", "cyan", "blue", "indigo", "purple", "pink", "red"]2627# FRAME2829def widen(cell):30 types = cell.types31 h, w = types.shape32 rows = h + 2 * MARGIN33 cols = math.ceil(2 * ASPECT * rows * H3 - 1)34 side = max(0, math.ceil((cols - w) / 2))35 side += side % 236 grid = np.full((rows, w + 2 * side), GRID, dtype=np.uint8)37 grid[MARGIN:MARGIN + h, side:side + w] = types38 cell.types = grid39 return cell4041# PAINT4243def rainbow(cell):44 palette = {45 VOID: [white],46 FILL: [black],47 GRID: gradient([ink(name) for name in HUES], STEPS),48 }49 seed(SEED)50 return cell.paint(palette, Mode.RANDOM)5152# CROP5354def crop(image):55 w, h = image.size56 box = round(w / ASPECT)57 if box <= h:58 top = (h - box) // 259 image = image.crop((0, top, w, top + box))60 else:61 box = round(h * ASPECT)62 left = (w - box) // 263 image = image.crop((left, 0, left + box, h))64 return image.convert("RGB").resize((WIDTH, round(WIDTH / ASPECT)), Image.LANCZOS)6566# RUN6768def main():69 ensure()70 cell = rainbow(widen(carpet_cut(NUMBER, LEVEL)))71 scale = math.ceil(2 * WIDTH / (cell.width + 1))72 image = draw(cell, scale=scale, start=cell.start)73 w, h = image.size74 image = crop(image.resize((w, round(h * H3)), Image.LANCZOS))75 image = quantize(image, COLORS)76 image.save(HERO, optimize=True)77 print("wrote %s %dx%d %.2f MB" % (show(HERO), *image.size, HERO.stat().st_size / 1e6))7879if __name__ == "__main__":80 main()