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:
|
||||
return
|
||||
|
||||
# Resize to fit window while maintaining aspect ratio
|
||||
height, width = display_frame.shape[:2]
|
||||
available_height = self.window_height - (0 if self.is_image_mode else self.TIMELINE_HEIGHT)
|
||||
# Get actual window dimensions (important for fullscreen mode)
|
||||
window_title = "Image Editor" if self.is_image_mode else "Video Editor"
|
||||
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
|
||||
|
||||
# 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"
|
||||
cv2.resizeWindow(window_title, self.window_width, 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
|
||||
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
|
||||
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_x = (self.window_width - frame_width) // 2
|
||||
start_x = (actual_width - frame_width) // 2
|
||||
|
||||
# Ensure frame fits within canvas bounds
|
||||
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_width = end_x - start_x
|
||||
|
||||
|
Reference in New Issue
Block a user