-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathoverlay.py
149 lines (114 loc) · 4.53 KB
/
overlay.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
import time
import tkinter as tk
import numpy as np
from PIL import ImageGrab, Image, ImageTk
# How often to update (in milliseconds), e.g., 50ms = 20 FPS
UPDATE_DELAY_MS = 50
# Choose a color that you will NOT draw with
TRANSPARENT_COLOR = "#fe01dc"
APP_NAME = "Overlay Example"
# Replace this function with your actual image processing logic
def process_image(screen):
"""
Processes the captured screen image.
Args:
screen (PIL.Image.Image): The captured screen image.
Returns:
A list of drawing commands for the overlay canvas.
Example command format:
("rectangle", x1, y1, x2, y2, outline_color, fill_color)
("text", x, y, text_content, fill_color, font_details)
("image", x, y, tk_photo_image)
"""
draw_commands = []
# Example: Crop the US box and convert to grayscale
# Coordinates match the Echo Wave GUI on a 1920x1080px display (adjust to match your setup)
us_box = (578, 280, 1343, 819)
us_pil = screen.crop(us_box).convert("L")
# Convert to a numpy array
us_np = np.array(us_pil)
# Example: Draw the mean US pixel value below the US box
draw_commands.append(
("text", 887, 902, f"{us_np.mean():>6.2f}", "yellow", ("Courier New", 24, "bold")))
# Example: Draw a red rectangle below the US box
draw_commands.append(("rectangle", 194, 839, 1726, 1009, "red", ""))
# Example: Draw a resized, flipped version of the US image to the right of the US box
small_us_pil = us_pil.resize((266, 187)).transpose(Image.FLIP_TOP_BOTTOM)
small_us_tk = ImageTk.PhotoImage(small_us_pil)
draw_commands.append(("image", 1460, 642, small_us_tk))
return draw_commands
# Tkinter overlay setup
root = tk.Tk()
root.title(APP_NAME)
# Get screen dimensions
screen_width = root.winfo_screenwidth()
screen_height = root.winfo_screenheight()
# Make window borderless, always on top, and cover the screen
root.overrideredirect(True)
root.geometry(f"{screen_width}x{screen_height}+0+0")
root.lift()
root.wm_attributes("-topmost", True)
# Configure for color key transparency
# Set root window background to the transparent color
root.config(bg=TRANSPARENT_COLOR)
# Set the attribute to make this color transparent
root.wm_attributes("-transparentcolor", TRANSPARENT_COLOR)
# Create Canvas with the same background color and no border
canvas = tk.Canvas(root, width=screen_width, height=screen_height,
bg=TRANSPARENT_COLOR, highlightthickness=0)
canvas.pack()
# Flag to signal the main loop to stop
running = True
# Store PhotoImage references to prevent garbage collection if drawing images
image_references = []
# Main update loop
def update_overlay():
global running, image_references
if not running:
root.destroy()
return
start_time = time.time()
# Capture screen
# Set bbox=(x, y, width, height) to specify a region or specific monitor
# For the primary monitor, None usually works
screenshot = ImageGrab.grab(bbox=None, all_screens=False)
# Process image
drawing_commands = process_image(screenshot)
# Update overlay canvas
# Clear previous drawings
canvas.delete("all")
image_references = []
# Execute drawing commands returned by process_image
for cmd in drawing_commands:
command_type = cmd[0]
if command_type == "rectangle":
_, x1, y1, x2, y2, outline_color, fill_color = cmd
canvas.create_rectangle(
x1, y1, x2, y2, outline=outline_color, fill=fill_color)
elif command_type == "text":
_, x, y, text, fill_color, font_details = cmd
canvas.create_text(x, y, text=text, fill=fill_color,
font=font_details, anchor=tk.NW)
elif command_type == "image":
_, x, y, tk_photo_image = cmd
canvas.create_image(x, y, image=tk_photo_image, anchor=tk.NW)
image_references.append(tk_photo_image)
elapsed_time = time.time() - start_time
# Ensure a delay of at least 1ms
delay = max(1, UPDATE_DELAY_MS - int(elapsed_time * 1000))
# Schedule the next update
root.after(delay, update_overlay)
# Exit mechanism
def quit_app(event=None):
global running
print("Exiting application")
running = False
# Bind the Q key press to the quit_app function
root.bind("<q>", quit_app)
# Start the application
print("Starting application")
print("Press Q in the overlay window to exit")
# Start the first update cycle after a brief moment
root.after(10, update_overlay)
# Start the Tkinter event loop
root.mainloop()