refactor(main.py): simplify and optimize coordinate conversion logic in VideoEditor class
This commit is contained in:
@@ -1103,10 +1103,12 @@ class VideoEditor:
|
|||||||
"""Convert screen coordinates to video frame coordinates and set crop"""
|
"""Convert screen coordinates to video frame coordinates and set crop"""
|
||||||
x, y, w, h = screen_rect
|
x, y, w, h = screen_rect
|
||||||
|
|
||||||
if self.current_display_frame is not None:
|
if self.current_display_frame is None:
|
||||||
|
return
|
||||||
|
|
||||||
# Get the original frame dimensions
|
# Get the original frame dimensions
|
||||||
original_height, original_width = self.current_display_frame.shape[:2]
|
original_height, original_width = self.current_display_frame.shape[:2]
|
||||||
available_height = self.window_height - self.TIMELINE_HEIGHT
|
available_height = self.window_height - (0 if self.is_image_mode else self.TIMELINE_HEIGHT)
|
||||||
|
|
||||||
# Calculate how the original frame is displayed (after crop/zoom/rotation)
|
# Calculate how the original frame is displayed (after crop/zoom/rotation)
|
||||||
display_frame = self.apply_crop_zoom_and_rotation(
|
display_frame = self.apply_crop_zoom_and_rotation(
|
||||||
@@ -1144,42 +1146,46 @@ class VideoEditor:
|
|||||||
display_w = min(display_w, display_width - display_x)
|
display_w = min(display_w, display_width - display_x)
|
||||||
display_h = min(display_h, display_height - display_y)
|
display_h = min(display_h, display_height - display_y)
|
||||||
|
|
||||||
# Convert display frame coordinates back to original frame coordinates
|
# Now we need to convert from the display frame coordinates back to original frame coordinates
|
||||||
# This is the inverse of apply_crop_zoom_and_rotation
|
# The display frame is the result of: original -> crop -> rotation -> zoom
|
||||||
# The order is: crop -> rotation -> zoom
|
|
||||||
# So we need to reverse: zoom -> rotation -> crop
|
|
||||||
|
|
||||||
# Step 1: Reverse zoom (zoom is applied to the rotated frame)
|
# Step 1: Reverse zoom
|
||||||
if self.zoom_factor != 1.0:
|
if self.zoom_factor != 1.0:
|
||||||
display_x = display_x / self.zoom_factor
|
display_x = display_x / self.zoom_factor
|
||||||
display_y = display_y / self.zoom_factor
|
display_y = display_y / self.zoom_factor
|
||||||
display_w = display_w / self.zoom_factor
|
display_w = display_w / self.zoom_factor
|
||||||
display_h = display_h / self.zoom_factor
|
display_h = display_h / self.zoom_factor
|
||||||
|
|
||||||
# Step 2: Reverse rotation (rotation is applied to the cropped frame)
|
# Step 2: Reverse rotation
|
||||||
if self.rotation_angle != 0:
|
if self.rotation_angle != 0:
|
||||||
# Get the dimensions after crop but before rotation
|
# Get the dimensions of the frame after crop but before rotation
|
||||||
if self.crop_rect:
|
if self.crop_rect:
|
||||||
crop_w, crop_h = int(self.crop_rect[2]), int(self.crop_rect[3])
|
crop_w, crop_h = int(self.crop_rect[2]), int(self.crop_rect[3])
|
||||||
else:
|
else:
|
||||||
crop_w, crop_h = original_width, original_height
|
crop_w, crop_h = original_width, original_height
|
||||||
|
|
||||||
# Apply inverse rotation to coordinates
|
# Apply inverse rotation to coordinates
|
||||||
|
# The key insight: we need to use the dimensions of the ROTATED frame for the coordinate transformation
|
||||||
|
# because the coordinates we have are in the rotated coordinate system
|
||||||
if self.rotation_angle == 90:
|
if self.rotation_angle == 90:
|
||||||
# 90° clockwise -> 270° counter-clockwise
|
# 90° clockwise rotation: (x,y) -> (y, rotated_width-x-w)
|
||||||
|
# The rotated frame has dimensions: height x width (swapped)
|
||||||
|
rotated_w, rotated_h = crop_h, crop_w
|
||||||
new_x = display_y
|
new_x = display_y
|
||||||
new_y = crop_w - display_x - display_w
|
new_y = rotated_w - display_x - display_w
|
||||||
new_w = display_h
|
new_w = display_h
|
||||||
new_h = display_w
|
new_h = display_w
|
||||||
elif self.rotation_angle == 180:
|
elif self.rotation_angle == 180:
|
||||||
# 180° -> 180° (same)
|
# 180° rotation: (x,y) -> (width-x-w, height-y-h)
|
||||||
new_x = crop_w - display_x - display_w
|
new_x = crop_w - display_x - display_w
|
||||||
new_y = crop_h - display_y - display_h
|
new_y = crop_h - display_y - display_h
|
||||||
new_w = display_w
|
new_w = display_w
|
||||||
new_h = display_h
|
new_h = display_h
|
||||||
elif self.rotation_angle == 270:
|
elif self.rotation_angle == 270:
|
||||||
# 270° clockwise -> 90° counter-clockwise
|
# 270° clockwise rotation: (x,y) -> (rotated_height-y-h, x)
|
||||||
new_x = crop_h - display_y - display_h
|
# The rotated frame has dimensions: height x width (swapped)
|
||||||
|
rotated_w, rotated_h = crop_h, crop_w
|
||||||
|
new_x = rotated_h - display_y - display_h
|
||||||
new_y = display_x
|
new_y = display_x
|
||||||
new_w = display_h
|
new_w = display_h
|
||||||
new_h = display_w
|
new_h = display_w
|
||||||
@@ -1188,7 +1194,7 @@ class VideoEditor:
|
|||||||
|
|
||||||
display_x, display_y, display_w, display_h = new_x, new_y, new_w, new_h
|
display_x, display_y, display_w, display_h = new_x, new_y, new_w, new_h
|
||||||
|
|
||||||
# Step 3: Reverse crop (crop is applied to the original frame)
|
# Step 3: Convert from cropped frame coordinates to original frame coordinates
|
||||||
original_x = display_x
|
original_x = display_x
|
||||||
original_y = display_y
|
original_y = display_y
|
||||||
original_w = display_w
|
original_w = display_w
|
||||||
|
|||||||
Reference in New Issue
Block a user