Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- # tk_pil_blob.py Starring Blobby Bobby
- import tkinter as tk
- from PIL import Image, ImageDraw, ImageTk, ImageFilter, ImageChops
- import math
- import os
- r0, g0, b0 = 180, 0, 180
- WW, HH = 400, 400
- x = y = 0
- mdrag = 0
- points = [(25, 120), (120, 110), (180, 30), (230, 130), (370, 20), (290, 150), (370, 370), (280, 220), (100, 360), (220, 170)]
- def get_xy():
- return root.winfo_pointerx() - root.winfo_rootx(), root.winfo_pointery() - root.winfo_rooty()
- def apply_color(value, threshold):
- return (r0, g0, b0, 255) if value > threshold else (0, 0, 0, 0)
- def blob(blur_amount, threshold):
- image = Image.new("RGBA", (WW, HH), (255, 255, 255, 0))
- draw = ImageDraw.Draw(image)
- draw.polygon(points, fill=(255, 255, 255, 255))
- blobby_image = image.filter(ImageFilter.GaussianBlur(blur_amount))
- mask = blobby_image.point(lambda p: 255 if p > threshold else 0)
- color = Image.new("RGBA", (WW, HH), (r0, g0, b0, 255))
- blobby_image.paste(color, mask=mask)
- blobby_image = blobby_image.filter(ImageFilter.GaussianBlur(2))
- return blobby_image
- def outline():
- image = Image.new("RGBA", (WW, HH), (0, 0, 0, 0))
- draw = ImageDraw.Draw(image)
- draw.polygon(points, outline=(0, 255, 0, 128))
- return image
- def update_image(*args):
- global mdrag
- x, y = get_xy()
- canvas.delete('all')
- blur_amount = blur_scroll.get()
- threshold = threshold_scroll.get()
- blobby_image = blob(blur_amount, threshold)
- canvas.image = ImageTk.PhotoImage(blobby_image)
- canvas.create_image(WW//2, HH//2, image=canvas.image, anchor='center')
- canvas.create_polygon(points, fill='', outline='#00ff00', width=3)
- if mdrag and (x < WW) and not selected_point:
- nearest_line_index = nearest_line(x, y)
- x1, y1 = points[nearest_line_index]
- x2, y2 = points[(nearest_line_index + 1) % (len(points))]
- canvas.create_line(x1, y1, x2, y2, fill='#ffff00', width=7)
- tag = {}
- for i in range(-3, 4):
- for j in range(-3, 4):
- color = '#fe9900'
- if i or j:
- color = '#ffffff'
- tag[(i, j)] = canvas.create_text(30 + i, 30 + j, text=nearest_line_index, font='verdana 30', fill=color)
- canvas.tag_raise(tag[(0, 0)])
- for point in points:
- x, y = point
- canvas.create_rectangle((x-2, y-2, x+2, y+2), fill='#000000')
- mdrag = 0
- def nearest_line(x, y):
- lines = {}
- for i in range(len(points) - 1):
- x1, y1 = points[i]
- x2, y2 = points[i + 1]
- distance = distance = get_distances(x, y, x1, y1, x2, y2)
- lines[i] = distance
- x1, y1 = points[0]
- x2, y2 = points[-1]
- distance = get_distances(x, y, x1, y1, x2, y2)
- lines[i + 1] = distance
- return min(lines, key=lines.get)
- def nearest_point(x, y):
- lines = {}
- for i in range(len(points)):
- x0, y0 = points[i]
- distance = math.sqrt((x - x0) ** 2 + (y - y0) ** 2)
- lines[i] = distance
- closest_point = min(lines, key=lines.get)
- del points[closest_point]
- def get_distances(x, y, x1, y1, x2, y2):
- line_distance = get_distance(x1, y1, x2, y2)
- XYp1_distance = get_distance(x, y, x1, y1)
- XYp2_distance = get_distance(x, y, x2, y2)
- return (XYp1_distance + XYp2_distance) - line_distance
- def get_distance(x1, y1, x2, y2):
- return math.sqrt((x2 - x1) ** 2 + (y2 - y1) ** 2)
- def print_points(event):
- os.system('cls' if os.name == 'nt' else 'clear')
- print(f"points = {points}")
- def on_drag(event):
- global mdrag
- mdrag = 1
- if selected_point:
- x, y = event.x, event.y
- points[selected_point - 1] = (x, y)
- update_image()
- def on_right_click(event):
- x, y = get_xy()
- if event.state & 0x0001: # Check if Shift key is pressed
- nearest_point(x, y)
- else:
- closest_line = nearest_line(x, y)
- points.insert(closest_line + 1, (x, y))
- update_image()
- def on_left_click(event):
- global selected_point
- x, y = get_xy()
- min_distance = 9
- selected_point = None
- for i, point in enumerate(points):
- distance = ((point[0] - x) ** 2 + (point[1] - y) ** 2) ** 0.5
- if distance < min_distance:
- min_distance = distance
- selected_point = i + 1
- def on_release(event):
- update_image()
- root = tk.Tk()
- root.title("Solid Blob")
- frame = tk.Frame(root)
- frame.pack(fill=tk.BOTH, expand=True)
- canvas = tk.Canvas(frame, width=WW, height=HH)
- canvas.grid(row=0, column=0)
- scroll_frame = tk.Frame(frame)
- scroll_frame.grid(row=0, column=1, sticky='ns')
- blur_scroll = tk.Scale(scroll_frame, from_=0, to_=50, orient='vertical', label='Blur')
- blur_scroll.set(25) # Default blur amount
- blur_scroll.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)
- threshold_scroll = tk.Scale(scroll_frame, from_=0, to_=255, orient='vertical', label='Threshold')
- threshold_scroll.set(25) # Default threshold
- threshold_scroll.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)
- blur_scroll.config(command=update_image)
- threshold_scroll.config(command=update_image)
- update_image()
- root.bind("<Button-1>", on_left_click)
- root.bind("<Button-3>", on_right_click)
- root.bind("<B1-Motion>", on_drag)
- root.bind("<ButtonRelease-1>", on_release)
- root.bind("<space>", print_points)
- root.mainloop()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement