|
import tkinter as tk
|
|
from PIL import Image, ImageTk
|
|
import json
|
|
|
|
class CoordinateVisualizer:
|
|
def __init__(self, master, image_path):
|
|
self.master = master
|
|
self.master.title("Video Area Coordinate Visualizer")
|
|
|
|
|
|
self.original_image = Image.open(image_path)
|
|
self.image_ratio = self.original_image.width / self.original_image.height
|
|
|
|
|
|
screen_width = self.master.winfo_screenwidth() * 0.8
|
|
screen_height = self.master.winfo_screenheight() * 0.8
|
|
|
|
|
|
width_ratio = screen_width / self.original_image.width
|
|
height_ratio = screen_height / self.original_image.height
|
|
self.scale_factor = min(width_ratio, height_ratio)
|
|
|
|
|
|
new_width = int(self.original_image.width * self.scale_factor)
|
|
new_height = int(self.original_image.height * self.scale_factor)
|
|
self.bg_image = self.original_image.resize((new_width, new_height), Image.LANCZOS)
|
|
self.bg_photo = ImageTk.PhotoImage(self.bg_image)
|
|
|
|
|
|
self.canvas = tk.Canvas(master, width=new_width, height=new_height)
|
|
self.canvas.pack(side=tk.LEFT)
|
|
self.canvas.create_image(0, 0, anchor=tk.NW, image=self.bg_photo)
|
|
|
|
|
|
self.start_x = self.start_y = self.end_x = self.end_y = 0
|
|
self.rect_id = None
|
|
|
|
|
|
self.canvas.bind("<ButtonPress-1>", self.on_press)
|
|
self.canvas.bind("<B1-Motion>", self.on_drag)
|
|
self.canvas.bind("<ButtonRelease-1>", self.on_release)
|
|
|
|
|
|
self.coord_frame = tk.Frame(master)
|
|
self.coord_frame.pack(side=tk.RIGHT, padx=10)
|
|
|
|
self.start_label = tk.Label(self.coord_frame, text="Start (x, y): (0, 0)")
|
|
self.start_label.pack()
|
|
|
|
self.end_label = tk.Label(self.coord_frame, text="End (x, y): (0, 0)")
|
|
self.end_label.pack()
|
|
|
|
self.size_label = tk.Label(self.coord_frame, text="Size (w, h): (0, 0)")
|
|
self.size_label.pack()
|
|
|
|
|
|
self.save_button = tk.Button(self.coord_frame, text="Save Coordinates", command=self.save_coordinates)
|
|
self.save_button.pack(pady=10)
|
|
|
|
def scaled_to_original(self, x, y):
|
|
return int(x / self.scale_factor), int(y / self.scale_factor)
|
|
|
|
def on_press(self, event):
|
|
self.start_x = self.canvas.canvasx(event.x)
|
|
self.start_y = self.canvas.canvasy(event.y)
|
|
|
|
if self.rect_id:
|
|
self.canvas.delete(self.rect_id)
|
|
|
|
self.rect_id = self.canvas.create_rectangle(self.start_x, self.start_y, self.start_x, self.start_y, outline='red')
|
|
|
|
def on_drag(self, event):
|
|
cur_x = self.canvas.canvasx(event.x)
|
|
cur_y = self.canvas.canvasy(event.y)
|
|
|
|
self.canvas.coords(self.rect_id, self.start_x, self.start_y, cur_x, cur_y)
|
|
self.update_labels(cur_x, cur_y)
|
|
|
|
def on_release(self, event):
|
|
self.end_x = self.canvas.canvasx(event.x)
|
|
self.end_y = self.canvas.canvasy(event.y)
|
|
self.update_labels(self.end_x, self.end_y)
|
|
|
|
def update_labels(self, cur_x, cur_y):
|
|
orig_start_x, orig_start_y = self.scaled_to_original(self.start_x, self.start_y)
|
|
orig_cur_x, orig_cur_y = self.scaled_to_original(cur_x, cur_y)
|
|
|
|
self.start_label.config(text=f"Start (x, y): ({orig_start_x}, {orig_start_y})")
|
|
self.end_label.config(text=f"End (x, y): ({orig_cur_x}, {orig_cur_y})")
|
|
|
|
width = abs(orig_cur_x - orig_start_x)
|
|
height = abs(orig_cur_y - orig_start_y)
|
|
self.size_label.config(text=f"Size (w, h): ({width}, {height})")
|
|
|
|
def save_coordinates(self):
|
|
start_x, start_y = self.scaled_to_original(min(self.start_x, self.end_x), min(self.start_y, self.end_y))
|
|
end_x, end_y = self.scaled_to_original(max(self.start_x, self.end_x), max(self.start_y, self.end_y))
|
|
|
|
coordinates = {
|
|
"start_x": start_x,
|
|
"start_y": start_y,
|
|
"end_x": end_x,
|
|
"end_y": end_y
|
|
}
|
|
with open("video_area_coordinates.json", "w") as f:
|
|
json.dump(coordinates, f)
|
|
print("Coordinates saved to video_area_coordinates.json")
|
|
|
|
if __name__ == "__main__":
|
|
root = tk.Tk()
|
|
app = CoordinateVisualizer(root, "background.png")
|
|
root.mainloop() |