Refactor video frame resizing logic in VideoEditor to maintain aspect ratio and improve window handling
This commit enhances the video frame resizing process by calculating actual window dimensions and ensuring that the video maintains its aspect ratio when displayed. It introduces a more robust method for determining available space and scaling the video frame accordingly, preventing upscaling beyond screen limits. Additionally, the canvas size is adjusted to match the actual window dimensions, improving the overall user experience during video editing.
This commit is contained in:
@@ -2880,38 +2880,67 @@ class VideoEditor:
|
|||||||
if display_frame is None:
|
if display_frame is None:
|
||||||
return
|
return
|
||||||
|
|
||||||
# Resize to fit window while maintaining aspect ratio
|
# Get actual window dimensions (important for fullscreen mode)
|
||||||
height, width = display_frame.shape[:2]
|
|
||||||
available_height = self.window_height - (0 if self.is_image_mode else self.TIMELINE_HEIGHT)
|
|
||||||
|
|
||||||
# Don't downscale - keep original video quality
|
|
||||||
# If video is larger than window, we'll handle it by resizing the window
|
|
||||||
scale = min(self.window_width / width, available_height / height)
|
|
||||||
if scale < 1.0:
|
|
||||||
# Resize window to fit video instead of downscaling video
|
|
||||||
new_window_width = int(width * 1.1) # Add 10% padding
|
|
||||||
new_window_height = int(height * 1.1) + (0 if self.is_image_mode else self.TIMELINE_HEIGHT)
|
|
||||||
|
|
||||||
# Update window size
|
|
||||||
self.window_width = new_window_width
|
|
||||||
self.window_height = new_window_height
|
|
||||||
|
|
||||||
# Resize the OpenCV window
|
|
||||||
window_title = "Image Editor" if self.is_image_mode else "Video Editor"
|
window_title = "Image Editor" if self.is_image_mode else "Video Editor"
|
||||||
cv2.resizeWindow(window_title, self.window_width, self.window_height)
|
try:
|
||||||
|
window_rect = cv2.getWindowImageRect(window_title)
|
||||||
|
if window_rect[2] > 0 and window_rect[3] > 0: # width and height > 0
|
||||||
|
actual_width = window_rect[2]
|
||||||
|
actual_height = window_rect[3]
|
||||||
|
else:
|
||||||
|
# Fallback to stored dimensions
|
||||||
|
actual_width = self.window_width
|
||||||
|
actual_height = self.window_height
|
||||||
|
except:
|
||||||
|
# Fallback to stored dimensions
|
||||||
|
actual_width = self.window_width
|
||||||
|
actual_height = self.window_height
|
||||||
|
|
||||||
|
# Calculate available space for video (accounting for timeline)
|
||||||
|
available_height = actual_height - (0 if self.is_image_mode else self.TIMELINE_HEIGHT)
|
||||||
|
|
||||||
|
# Get original video dimensions to maintain aspect ratio
|
||||||
|
height, width = display_frame.shape[:2]
|
||||||
|
|
||||||
|
# Calculate scale to fit video in available space while maintaining aspect ratio
|
||||||
|
scale_x = actual_width / width
|
||||||
|
scale_y = available_height / height
|
||||||
|
scale = min(scale_x, scale_y) # Use the smaller scale to ensure video fits
|
||||||
|
|
||||||
|
# Ensure scale is never greater than 1.0 to prevent upscaling beyond screen
|
||||||
|
scale = min(scale, 1.0)
|
||||||
|
|
||||||
|
# Calculate scaled dimensions
|
||||||
|
scaled_width = int(width * scale)
|
||||||
|
scaled_height = int(height * scale)
|
||||||
|
|
||||||
|
# Double-check that scaled dimensions fit within available space
|
||||||
|
if scaled_height > available_height:
|
||||||
|
scale = available_height / height
|
||||||
|
scaled_width = int(width * scale)
|
||||||
|
scaled_height = int(height * scale)
|
||||||
|
|
||||||
|
if scaled_width > actual_width:
|
||||||
|
scale = actual_width / width
|
||||||
|
scaled_width = int(width * scale)
|
||||||
|
scaled_height = int(height * scale)
|
||||||
|
|
||||||
|
# Resize the frame to fit the window while maintaining aspect ratio
|
||||||
|
if scale != 1.0:
|
||||||
|
display_frame = cv2.resize(display_frame, (scaled_width, scaled_height), interpolation=cv2.INTER_LINEAR)
|
||||||
|
|
||||||
# Create canvas with timeline space
|
# Create canvas with timeline space
|
||||||
canvas = np.zeros((self.window_height, self.window_width, 3), dtype=np.uint8)
|
canvas = np.zeros((actual_height, actual_width, 3), dtype=np.uint8)
|
||||||
|
|
||||||
# Center the frame on canvas
|
# Center the frame on canvas
|
||||||
frame_height, frame_width = display_frame.shape[:2]
|
frame_height, frame_width = display_frame.shape[:2]
|
||||||
available_height = self.window_height - (0 if self.is_image_mode else self.TIMELINE_HEIGHT)
|
available_height = actual_height - (0 if self.is_image_mode else self.TIMELINE_HEIGHT)
|
||||||
start_y = (available_height - frame_height) // 2
|
start_y = (available_height - frame_height) // 2
|
||||||
start_x = (self.window_width - frame_width) // 2
|
start_x = (actual_width - frame_width) // 2
|
||||||
|
|
||||||
# Ensure frame fits within canvas bounds
|
# Ensure frame fits within canvas bounds
|
||||||
end_y = min(start_y + frame_height, available_height)
|
end_y = min(start_y + frame_height, available_height)
|
||||||
end_x = min(start_x + frame_width, self.window_width)
|
end_x = min(start_x + frame_width, actual_width)
|
||||||
actual_frame_height = end_y - start_y
|
actual_frame_height = end_y - start_y
|
||||||
actual_frame_width = end_x - start_x
|
actual_frame_width = end_x - start_x
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user