Enhance crop application with motion tracking in VideoEditor

This commit updates the crop functionality to incorporate motion tracking offsets, ensuring that the crop center aligns with tracked points when motion tracking is enabled. It also refines the handling of crop adjustments and display offsets, improving the overall user experience during video editing. Additionally, the key mappings for expanding crop dimensions have been corrected for clarity in user interactions.
This commit is contained in:
2025-09-16 14:43:46 +02:00
parent 04d914834e
commit 81f17953f7

View File

@@ -1241,10 +1241,17 @@ class VideoEditor:
# Apply brightness/contrast first (to original frame for best quality) # Apply brightness/contrast first (to original frame for best quality)
processed_frame = self.apply_brightness_contrast(processed_frame) processed_frame = self.apply_brightness_contrast(processed_frame)
# Apply crop # Apply crop with motion tracking
if self.crop_rect: if self.crop_rect:
x, y, w, h = self.crop_rect x, y, w, h = self.crop_rect
x, y, w, h = int(x), int(y), int(w), int(h) x, y, w, h = int(x), int(y), int(w), int(h)
# Apply motion tracking offset to move crop center to tracked point
if self.motion_tracker.tracking_enabled:
tracking_offset_x, tracking_offset_y = self.motion_tracker.get_tracking_offset(self.current_frame)
x += int(tracking_offset_x)
y += int(tracking_offset_y)
# Ensure crop is within frame bounds # Ensure crop is within frame bounds
x = max(0, min(x, processed_frame.shape[1] - 1)) x = max(0, min(x, processed_frame.shape[1] - 1))
y = max(0, min(y, processed_frame.shape[0] - 1)) y = max(0, min(y, processed_frame.shape[0] - 1))
@@ -1266,14 +1273,11 @@ class VideoEditor:
processed_frame, (new_width, new_height), interpolation=cv2.INTER_LINEAR processed_frame, (new_width, new_height), interpolation=cv2.INTER_LINEAR
) )
# Handle zoom center and display offset with motion tracking # Handle zoom center and display offset
if new_width > self.window_width or new_height > self.window_height: if new_width > self.window_width or new_height > self.window_height:
# Apply motion tracking offset to display offset
tracking_offset_x, tracking_offset_y = self.motion_tracker.get_tracking_offset(self.current_frame)
# Calculate crop from zoomed image to fit window # Calculate crop from zoomed image to fit window
start_x = max(0, self.display_offset[0] + int(tracking_offset_x)) start_x = max(0, self.display_offset[0])
start_y = max(0, self.display_offset[1] + int(tracking_offset_y)) start_y = max(0, self.display_offset[1])
end_x = min(new_width, start_x + self.window_width) end_x = min(new_width, start_x + self.window_width)
end_y = min(new_height, start_y + self.window_height) end_y = min(new_height, start_y + self.window_height)
processed_frame = processed_frame[start_y:end_y, start_x:end_x] processed_frame = processed_frame[start_y:end_y, start_x:end_x]
@@ -2224,6 +2228,13 @@ class VideoEditor:
# Add the crop offset to get back to original frame coordinates # Add the crop offset to get back to original frame coordinates
if self.crop_rect: if self.crop_rect:
crop_x, crop_y, crop_w, crop_h = self.crop_rect crop_x, crop_y, crop_w, crop_h = self.crop_rect
# Account for motion tracking offset that was applied to the crop
if self.motion_tracker.tracking_enabled:
tracking_offset_x, tracking_offset_y = self.motion_tracker.get_tracking_offset(self.current_frame)
crop_x -= int(tracking_offset_x)
crop_y -= int(tracking_offset_y)
original_x += crop_x original_x += crop_x
original_y += crop_y original_y += crop_y
@@ -3232,14 +3243,14 @@ class VideoEditor:
print("No render operation to cancel") print("No render operation to cancel")
# Individual direction controls using shift combinations we can detect # Individual direction controls using shift combinations we can detect
elif key == ord("J"): # Shift+j - expand up (relative to rotation) elif key == ord("J"): # Shift+j - expand down (relative to rotation)
direction = self.get_rotated_direction('j') direction = self.get_rotated_direction('j')
self.adjust_crop_size(direction, False) self.adjust_crop_size(direction, False)
print(f"Expanded crop upward by {self.crop_size_step}px") print(f"Expanded crop downward by {self.crop_size_step}px")
elif key == ord("K"): # Shift+k - expand down (relative to rotation) elif key == ord("K"): # Shift+k - expand up (relative to rotation)
direction = self.get_rotated_direction('k') direction = self.get_rotated_direction('k')
self.adjust_crop_size(direction, False) self.adjust_crop_size(direction, False)
print(f"Expanded crop downward by {self.crop_size_step}px") print(f"Expanded crop upward by {self.crop_size_step}px")
elif key == ord("L"): # Shift+l - expand right (relative to rotation) elif key == ord("L"): # Shift+l - expand right (relative to rotation)
direction = self.get_rotated_direction('l') direction = self.get_rotated_direction('l')
self.adjust_crop_size(direction, False) self.adjust_crop_size(direction, False)