Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- # tk_PIL_Control.py
- import tkinter as tk
- from tkinter import ttk
- from PIL import Image, ImageTk, ImageDraw, ImageFont, ImageFilter, ImageEnhance, ImageChops
- import math
- from itertools import combinations
- import random
- WW, HH = 640, 640
- cx, cy = WW // 2 - 1, HH // 2 - 1
- w, h = WW * 2, WW * 2
- zoom_factor = 0.9
- sz = 59
- root = tk.Tk()
- root.title("# tk_PIL_Control.py")
- root.geometry('+0+0')
- canvas = tk.Canvas(root, width=WW, height=HH)
- canvas.pack()
- base = {
- (0, 0): (255, 255, 255), (0, 1): (255, 255, 0), (0, 2): (0, 255, 0),
- (1, 0): (255, 128, 0), (1, 1): (128, 128, 128), (1, 2): (0, 0, 255),
- (2, 0): (255, 0, 0), (2, 1): (128, 0, 128), (2, 2): (0, 0, 0)
- }
- small_img = Image.new('RGB', (3, 3))
- for y in range(3):
- for x in range(3):
- small_img.putpixel((x, y), base[(x, y)])
- init_img = small_img.resize((WW, HH), Image.LANCZOS).convert("RGBA")
- base_img = init_img.copy()
- colors = [(255, 192, 203), (165, 42, 42), (0, 255, 255)]
- colors = list(base.values()) + colors
- pairs = list(combinations(colors, 2))
- combos = []
- used_pairs = set()
- current_pair = pairs.pop(0)
- combos.extend(current_pair)
- used_pairs.add(current_pair)
- while pairs:
- last_color = combos[-1]
- next_pair = None
- for p in pairs:
- if p not in used_pairs:
- if p == last_color:
- next_pair = p
- rev = False
- break
- elif p == last_color:
- next_pair = p
- rev = True
- break
- if next_pair:
- pairs.remove(next_pair)
- used_pairs.add(next_pair)
- if rev:
- combos.append(next_pair[0])
- else:
- combos.append(next_pair[1])
- else:
- p = pairs.pop(0)
- used_pairs.add(p)
- combos.extend(p)
- gradient_width = 80
- total_width = len(combos) * gradient_width
- gradient_img = Image.new("RGB", (len(combos), 1))
- for i, color in enumerate(combos):
- gradient_img.putpixel((i, 0), color)
- gradient_img = gradient_img.resize((total_width, 1), resample=Image.LANCZOS)
- colors_data = list(gradient_img.getdata())
- mid4_cache = [(cx + px, cy + py) for (px, py) in [(0, 0), (0, 1), (1, 0), (1, 1)]]
- new_sz = int(WW * zoom_factor)
- TL = (WW - new_sz) // 2
- BR = TL + new_sz
- photo = ImageTk.PhotoImage(base_img)
- canvas.create_image(0, 0, anchor=tk.NW, image=photo)
- ctrl_win = tk.Toplevel(root)
- ctrl_win.title("PIL/Cache Control")
- ctrl_win.geometry('600x660+660+0')
- main_frame = tk.Frame(ctrl_win)
- main_frame.pack(fill='both', expand=True)
- ctrl_canvas = tk.Canvas(main_frame, borderwidth=0)
- scrollbar = ttk.Scrollbar(main_frame, orient="vertical", command=ctrl_canvas.yview)
- scroll_content = tk.Frame(ctrl_canvas)
- scroll_content.bind("<Configure>", lambda e: ctrl_canvas.configure(scrollregion=ctrl_canvas.bbox("all")))
- ctrl_canvas.create_window((0, 0), window=scroll_content, anchor="nw")
- ctrl_canvas.configure(yscrollcommand=scrollbar.set)
- ctrl_canvas.pack(side="left", fill="both", expand=True)
- scrollbar.pack(side="right", fill="y")
- pil_modes = [
- {"label": "Absolute Difference", "id": "difference", "var": tk.BooleanVar(value=True)},
- {"label": "Standard Multiply", "id": "multiply", "var": tk.BooleanVar(value=False)},
- {"label": "Screen Brighten", "id": "screen", "var": tk.BooleanVar(value=False)},
- {"label": "Darker Extraction", "id": "darker", "var": tk.BooleanVar(value=False)},
- {"label": "Lighter Extraction", "id": "lighter", "var": tk.BooleanVar(value=False)},
- {"label": "Add Linear (Clipped)", "id": "add", "var": tk.BooleanVar(value=False)},
- {"label": "Add Modulo (Wrap)", "id": "add_modulo", "var": tk.BooleanVar(value=False)},
- {"label": "Subtract (Clipped)", "id": "subtract", "var": tk.BooleanVar(value=False)},
- {"label": "Subtract Modulo", "id": "subtract_modulo", "var": tk.BooleanVar(value=False)},
- {"label": "Hard Light Sharpness", "id": "hard_light", "var": tk.BooleanVar(value=False)},
- {"label": "Soft Light Gradients", "id": "soft_light", "var": tk.BooleanVar(value=False)},
- {"label": "Overlay Blend", "id": "overlay", "var": tk.BooleanVar(value=False)},
- {"label": "Invert Channels Pass", "id": "invert", "var": tk.BooleanVar(value=False)},
- {"label": "Logical Bitwise AND", "id": "logical_and", "var": tk.BooleanVar(value=False)},
- {"label": "Logical Bitwise OR", "id": "logical_or", "var": tk.BooleanVar(value=False)},
- {"label": "Logical Bitwise XOR", "id": "logical_xor", "var": tk.BooleanVar(value=False)}
- ]
- blend_alpha = tk.DoubleVar(value=0.01)
- refresh = False
- def trigger_restart():
- global refresh
- refresh = True
- row_frames = []
- def move_up(idx):
- if idx > 0:
- pil_modes[idx], pil_modes[idx-1] = pil_modes[idx-1], pil_modes[idx]
- rebuild_ui_list()
- def move_down(idx):
- if idx < len(pil_modes) - 1:
- pil_modes[idx], pil_modes[idx+1] = pil_modes[idx+1], pil_modes[idx]
- rebuild_ui_list()
- def rebuild_ui_list():
- global row_frames
- for frame in row_frames:
- frame.destroy()
- row_frames.clear()
- for i, mode in enumerate(pil_modes):
- f = tk.Frame(list_container)
- f.grid(row=i, column=0, sticky='w', pady=2)
- row_frames.append(f)
- btn_up = ttk.Button(f, text="^", width=3, command=lambda idx=i: move_up(idx))
- btn_up.pack(side='left', padx=2)
- btn_down = ttk.Button(f, text="v", width=3, command=lambda idx=i: move_down(idx))
- btn_down.pack(side='left', padx=2)
- chk = ttk.Checkbutton(f, text=mode["label"], variable=mode["var"])
- chk.pack(side='left', padx=5)
- ttk.Label(scroll_content, text="Configurations:", font=('Helvetica', 10, 'bold')).pack(anchor=tk.W, padx=10, pady=5)
- list_container = tk.Frame(scroll_content)
- list_container.pack(fill='both', expand=True, padx=10)
- list_container.columnconfigure(0, weight=2)
- list_container.columnconfigure(1, weight=1)
- rebuild_ui_list()
- btn_restart = ttk.Button(list_container, text="Reset Buffer", command=trigger_restart)
- btn_restart.grid(row=3, column=1, sticky='ew', padx=15, pady=5)
- alpha_header_frame = tk.Frame(scroll_content)
- alpha_header_frame.pack(fill='x', padx=10)
- ttk.Label(alpha_header_frame, text="Blend Strength:", font=('Helvetica', 10, 'bold')).pack(side='left')
- lbl_alpha_val = ttk.Label(alpha_header_frame, text=blend_alpha.get(), font=('Helvetica', 10, 'bold'), foreground="blue")
- lbl_alpha_val.pack(side='right', padx=10)
- alpha = 0
- while 1:
- if refresh:
- base_img = init_img.copy()
- refresh = False
- base_img = base_img.crop((TL, TL, BR, BR))
- base_img = base_img.resize((WW, HH), Image.LANCZOS)
- px_base = base_img.load()
- rgb = colors_data.pop(0)
- colors_data.append(rgb)
- for x, y in mid4_cache:
- px_base[x, y] = (*rgb, 255)
- current_pass = base_img.copy()
- active_ops = [mode["id"] for mode in pil_modes if mode["var"].get()]
- fractal_img = ImageChops.blend(base_img, current_pass, alpha)
- base_img = fractal_img.copy()
- photo.paste(fractal_img)
- root.update()
Advertisement
Add Comment
Please, Sign In to add comment