Advertisement
here2share

# tk_Text_To_Compact.py

Jan 5th, 2025 (edited)
84
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 6.97 KB | None | 0 0
  1. # tk_Text_To_Compact.py
  2.  
  3. import tkinter as tk
  4. from tkinter import colorchooser
  5. from PIL import Image, ImageDraw, ImageTk, ImageFont, ImageChops
  6. import os
  7. import tempfile
  8. import subprocess
  9. import platform
  10. import random
  11.  
  12. WW = 600
  13. HH = 600
  14.  
  15. root = tk.Tk()
  16. root.title("Text To Compact")
  17. root.geometry("+10+10")
  18.  
  19. left_frame = tk.Frame(root)
  20. left_frame.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)
  21.  
  22. right_frame = tk.Frame(root)
  23. right_frame.pack(side=tk.RIGHT, fill=tk.Y)
  24.  
  25. canvas = tk.Canvas(left_frame, width=WW, height=HH)
  26. scrollbar = tk.Scrollbar(left_frame, orient="vertical", command=canvas.yview)
  27. canvas.configure(yscrollcommand=scrollbar.set)
  28.  
  29. canvas.pack(side="left", fill="both", expand=True)
  30. scrollbar.pack(side="right", fill="y")
  31.  
  32. font_listbox = tk.Listbox(right_frame, width=40, height=30)
  33. font_listbox.pack(side=tk.LEFT, fill=tk.Y)
  34.  
  35. scrollbar = tk.Scrollbar(right_frame, orient=tk.VERTICAL)
  36. scrollbar.config(command=font_listbox.yview)
  37. scrollbar.pack(side=tk.RIGHT, fill=tk.Y)
  38. font_listbox.config(yscrollcommand=scrollbar.set)
  39.  
  40. max_width = 580
  41. padding = 10
  42.  
  43. avoid = '''
  44. holomdl2
  45. marlett
  46. segmdl2
  47. symbol
  48. webdings
  49. wingding
  50. '''
  51.  
  52. def copy_canvas_to_clipboard():
  53.     bbox = canvas.bbox("all")
  54.  
  55.     x0, y0, x1, y1 = bbox
  56.     total_width = (x1 - x0) + padding * 2
  57.     total_height = (y1 - y0) + padding * 2
  58.  
  59.     img = Image.new("RGBA", (total_width, total_height), (255, 255, 255, 255))
  60.  
  61.     paste_y = padding
  62.     for canvas_img, x, y in canvas_items:
  63.         if canvas_img.mode != "RGBA":
  64.             canvas_img = canvas_img.convert("RGBA")
  65.         img.paste(canvas_img, (x, paste_y), canvas_img)
  66.         paste_y += canvas_img.height + padding
  67.  
  68.     top = tk.Toplevel()
  69.     top.title("Canvas Copy")
  70.  
  71.     canvas_top = tk.Canvas(top, width=WW, height=HH)
  72.     canvas_top.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)
  73.  
  74.     scrollbar = tk.Scrollbar(top, orient="vertical", command=canvas_top.yview)
  75.     scrollbar.pack(side=tk.RIGHT, fill=tk.Y)
  76.  
  77.     canvas_top.configure(yscrollcommand=scrollbar.set)
  78.     canvas_top.bind(
  79.         "<Configure>",
  80.         lambda e: canvas_top.configure(scrollregion=canvas_top.bbox("all"))
  81.     )
  82.  
  83.     tk_img = ImageTk.PhotoImage(img)
  84.     canvas_top.create_image(0, 0, anchor='nw', image=tk_img)
  85.     canvas_top.image = tk_img
  86.     canvas_top.configure(scrollregion=canvas_top.bbox("all"))
  87.     root.update()
  88.  
  89.     with tempfile.NamedTemporaryFile(suffix=".png", delete=False) as tmp_file:
  90.         img.save(tmp_file.name)
  91.         tmp_file_path = tmp_file.name
  92.         print(f"Image saved to {tmp_file_path}")
  93.        
  94.     script = f'''
  95.     Add-Type -AssemblyName System.Windows.Forms
  96.     $image = [System.Drawing.Image]::FromFile("{tmp_file_path}")
  97.     [System.Windows.Forms.Clipboard]::SetImage($image)
  98.     '''
  99.     subprocess.run(["powershell", "-Command", script], check=True)
  100.  
  101.     os.remove(tmp_file_path)
  102.  
  103. menu_bar = tk.Menu(root)
  104. root.config(menu=menu_bar)
  105.  
  106. file_menu = tk.Menu(menu_bar, tearoff=0)
  107. menu_bar.add_cascade(label="Options", menu=file_menu)
  108. file_menu.add_command(label="Copy To Clipboard", command=copy_canvas_to_clipboard)
  109.  
  110. def on_mouse_wheel(event):
  111.     canvas.yview_scroll(int(-1 * (event.delta / 120)), "units")
  112.  
  113. canvas.bind_all("<MouseWheel>", on_mouse_wheel)
  114.  
  115. def on_font_select(event):
  116.     global font_name
  117.     selected_font = font_listbox.get(font_listbox.curselection())
  118.     font_name = selected_font
  119.  
  120. if platform.system() == "Windows":
  121.     fonts_dir = os.path.join(os.environ['WINDIR'], 'Fonts')
  122. else:
  123.     fonts_dir = "/usr/share/fonts"
  124.  
  125. font_lib = {}
  126. for sys_root, _, files in os.walk(fonts_dir):
  127.     for file in files:
  128.         if file.endswith(('.ttf', '.otf')):
  129.             font_path = os.path.join(sys_root, file)
  130.             font_name = font_path.split('\\')[-1].split('.')[0]
  131.             font_path = ImageFont.truetype(os.path.join(sys_root, file), size=600)
  132.             if font_name not in avoid:
  133.                 font_lib[font_name] = font_path
  134.                 font_listbox.insert(tk.END, font_name)
  135.  
  136. font_name = current_font = 'palai'
  137. if font_name not in font_lib:
  138.     font_name = current_font = random.choice(list(font_lib))
  139. sentence = "This is just a demo"
  140. words = sentence.split()
  141.  
  142. splits = []
  143. for i in range(0, len(words)):
  144.     for j in range(i + 1, len(words) + 1):
  145.         text = words[i:j]
  146.         text = " ".join(text)
  147.         if len(text) > 2:
  148.             splits.append(text)
  149.  
  150. def find_true_bbox(img, threshold=128):
  151.     if img.mode != "RGBA":
  152.         img = img.convert("RGBA")
  153.    
  154.     bg = Image.new("RGBA", img.size, img.getpixel((0, 0)))
  155.     diff = ImageChops.difference(img, bg)
  156.     diff = diff.convert("L")
  157.     diff = diff.point(lambda p: 255 if p > threshold else 0)
  158.     bbox = diff.getbbox()
  159.     return bbox
  160.  
  161. def on_canvas_click(canvas_id):
  162.     color = colorchooser.askcolor(title="Choose A Color")[1]
  163.     if color:
  164.         update_line(canvas_id, color)
  165.  
  166. def update_line(canvas_id, color):
  167.     text, font, bbox, buffer_draw, buffer_width, buffer_height, tk_img = line_data[canvas_id]
  168.     buffer_image = Image.new("RGBA", (6000, 1000), (255, 255, 255, 0))
  169.     buffer_draw = ImageDraw.Draw(buffer_image)
  170.     buffer_draw.text((50, 0), text, font=font, fill=color)
  171.     buffer_image = buffer_image.crop(bbox)
  172.     buffer_image = buffer_image.resize((buffer_width, buffer_height), Image.ANTIALIAS)
  173.  
  174.     tk_img = ImageTk.PhotoImage(buffer_image)
  175.     canvas.itemconfig(canvas_id, image=tk_img)
  176.     line_img[canvas_id] = tk_img
  177.    
  178.     idx = line_img[canvas_id, 'idx']
  179.    
  180.     img, padding, y_offset = canvas_items[idx]
  181.     canvas_items[idx] = buffer_image, padding, y_offset
  182.  
  183. line_data = {}
  184. def plot(img):
  185.     global y_offset
  186.     tk_img = ImageTk.PhotoImage(img)
  187.     canvas_id = canvas.create_image(padding, y_offset, anchor="nw", image=tk_img)
  188.     line_data[canvas_id] = (text, font_lib[font_name], bbox, ImageDraw.Draw(img), img.width, img.height, tk_img)
  189.     canvas.tag_bind(canvas_id, "<Button-1>", lambda event, idx=canvas_id: on_canvas_click(idx))
  190.     root.update()
  191.     line_img[canvas_id, 'idx'] = len(canvas_items)
  192.     canvas_items.append((img, padding, y_offset))
  193.     canvas.img = tk_img
  194.     y_offset += img.height + padding
  195.  
  196. font_listbox.bind("<<ListboxSelect>>", on_font_select)
  197.  
  198. font_size = 500
  199. while 1:
  200.     if font_name:
  201.         line_img = {}
  202.         canvas_items = []
  203.         canvas.configure(scrollregion=(0, 0, WW, 5000))
  204.         canvas.yview_moveto(0.0)
  205.         current_font = font_name
  206.         canvas.delete("all")
  207.         line_data = {}
  208.         y_offset = padding
  209.         print(f"Current font: {font_name}")
  210.         for text in splits:
  211.             if font_name == current_font:
  212.                 buffer_image = Image.new("RGBA", (6000, 1000), (255, 255, 255, 0))
  213.                 buffer_draw = ImageDraw.Draw(buffer_image)
  214.                 buffer_draw.text((50, 0), text, font=font_lib[font_name], fill="black")
  215.                 bbox = find_true_bbox(buffer_image, threshold=128)
  216.                 buffer_image = buffer_image.crop(bbox)
  217.                 buffer_width, buffer_height = buffer_image.size
  218.                 print(f"Text: {text}, BBox: {bbox}, Original size: {buffer_width}x{buffer_height}")
  219.                 buffer_height = int((max_width / buffer_width) * buffer_height)
  220.                 buffer_image = buffer_image.resize((max_width, buffer_height), Image.ANTIALIAS)
  221.                
  222.                 plot(buffer_image)
  223.             else:
  224.                 break
  225.            
  226.         if font_name == current_font:
  227.             canvas.configure(scrollregion=(0, 0, WW, y_offset))
  228.             root.update()
  229.             font_name = ''
  230.             print('*** done ***\n')
  231.  
  232.     root.update()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement