Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- # tk_water_caustic_ani.py
- from tkinter import *
- from PIL import Image, ImageTk, ImageFilter, ImageDraw
- from math import sin, cos, pi
- import random
- ww = 384
- hh = 384
- cx, cy = ww//2, hh//2
- root = Tk()
- root.title("tk_water_caustic_ani")
- root.geometry("%dx%d+0+0"%(ww,hh))
- def rgb2hex(r,g,b):
- return '#%02X%02X%02X'%(r,g,b)
- rgb = range(0, 256, 50)
- colors = [rgb2hex(r, g, b) for r in rgb for g in rgb for b in rgb]
- img = Image.new('RGB', (ww, hh), (0, 0, 0))
- draw = {}
- for k in (0, 1, 2, 3):
- draw[k] = ImageDraw.Draw(img)
- blur_radius = 0.04 * min(img.size)
- # set the minimum and maximum colors of the water
- min_color = (0, 80, 180)
- max_color = (0, 210, 250)
- # create a custom color palette for interpolation
- palette = [min_color] * 3
- for i in range(0,253,2):
- g = min_color[1] + (max_color[1] - min_color[1]) * i // 245
- b = min_color[2] + (max_color[2] - min_color[2]) * i // 245
- palette.append((0, g, b))
- for i in range(253,256):
- palette.append((255, 255, 255))
- palette = palette[1:-1]+palette[::-1]
- Lc = len(palette)
- canvas = Canvas(root, width=ww, height=hh, bg='white')
- canvas.pack(side=LEFT, fill=BOTH, expand=True)
- def display():
- tkimg = ImageTk.PhotoImage(draw['source'])
- canvas.create_image((cx, cy), image=tkimg)
- canvas.update()
- sz = 16
- c = 0
- xy = range(0, 512, sz)
- for y in xy:
- for x in xy:
- c = random.randint(0, 50)
- color = colors.pop(c)
- colors.append(color)
- draw[1].rectangle((x, y, x+sz, y+sz), fill=color, outline=color)
- draw['source'] = img.filter(ImageFilter.GaussianBlur(radius=blur_radius))
- source = {}
- target = {}
- for y in range(hh):
- for x in range(ww):
- source[x,y] = draw['source'].getpixel((x, y))
- def wave_transition(x, y, alpha):
- source_color = source[x, y]
- target_color = draw['target'].getpixel((x, y))
- r = int((1 - alpha) * source_color[0] + alpha * target_color[0])
- g = int((1 - alpha) * source_color[1] + alpha * target_color[1])
- b = int((1 - alpha) * source_color[2] + alpha * target_color[2])
- # apply the custom color palette
- color = int(r + g + b) % Lc
- draw['source'].putpixel((x, y), palette[color])
- def waves():
- alpha = 0.1
- while alpha < 0.8:
- for y in range(hh):
- for x in range(ww):
- wave_transition(x, y, alpha)
- alpha += 0.1
- display()
- for y in range(hh):
- for x in range(ww):
- target_color = draw['target'].getpixel((x, y))
- wave_transition(x, y, alpha=0.9)
- source[x, y] = target_color # fastest solution I can think of
- display()
- while 1:
- for y in xy:
- c = (c + 1) % 11
- for x in xy:
- color = colors.pop(c)
- colors.append(color)
- draw[0].rectangle((x, y, x+sz, y+sz), fill=color, outline=color)
- c = (c + 1) % 11
- draw['target'] = img.filter(ImageFilter.GaussianBlur(radius=blur_radius))
- waves()
Advertisement
Advertisement