diff --git a/main.py b/main.py index a549f95..8b3055a 100644 --- a/main.py +++ b/main.py @@ -120,6 +120,20 @@ class MediaGrader: # Performance optimization: Thread pool for parallel operations self.thread_pool = ThreadPoolExecutor(max_workers=4) + def display_with_aspect_ratio(self, frame): + """Display frame while maintaining aspect ratio""" + if frame is None: + return + + # Log frame dimensions + height, width = frame.shape[:2] + + # Force window to resize to match the frame dimensions + cv2.resizeWindow("Media Grader", width, height) + + # Display the frame + cv2.imshow("Media Grader", frame) + def find_media_files(self) -> List[Path]: """Find all media files recursively in the directory""" media_files = [] @@ -958,7 +972,8 @@ class MediaGrader: # Draw timeline self.draw_timeline(frame) - cv2.imshow("Media Grader", frame) + # Maintain aspect ratio when displaying + self.display_with_aspect_ratio(frame) def display_multi_segment_frame(self): """Display multi-segment frame view""" @@ -991,8 +1006,19 @@ class MediaGrader: row = i // grid_cols col = i % grid_cols - # Resize segment frame to fit grid cell - resized_segment = cv2.resize(segment_frame, (segment_width, segment_height)) + # Resize segment frame to fit grid cell while maintaining aspect ratio + frame_height, frame_width = segment_frame.shape[:2] + seg_scale_x = segment_width / frame_width + seg_scale_y = segment_height / frame_height + seg_scale = min(seg_scale_x, seg_scale_y) + + new_seg_width = int(frame_width * seg_scale) + new_seg_height = int(frame_height * seg_scale) + resized_segment = cv2.resize(segment_frame, (new_seg_width, new_seg_height), interpolation=cv2.INTER_AREA) + + # Center the resized segment in the grid cell + y_offset = (segment_height - new_seg_height) // 2 + x_offset = (segment_width - new_seg_width) // 2 # Calculate position in combined frame y_start = row * segment_height @@ -1000,8 +1026,17 @@ class MediaGrader: x_start = col * segment_width x_end = x_start + segment_width - # Place segment in combined frame - combined_frame[y_start:y_end, x_start:x_end] = resized_segment + # Place segment in combined frame (centered) + y_place_start = y_start + y_offset + y_place_end = y_place_start + new_seg_height + x_place_start = x_start + x_offset + x_place_end = x_place_start + new_seg_width + + # Ensure we don't go out of bounds + y_place_end = min(y_place_end, y_end) + x_place_end = min(x_place_end, x_end) + + combined_frame[y_place_start:y_place_end, x_place_start:x_place_end] = resized_segment # Add segment label segment_position = int((self.segment_positions[i] / self.total_frames) * 100) @@ -1009,7 +1044,7 @@ class MediaGrader: cv2.putText( combined_frame, label_text, - (x_start + 5, y_start + 20), + (x_place_start + 5, y_place_start + 20), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255, 255, 255), @@ -1018,7 +1053,7 @@ class MediaGrader: cv2.putText( combined_frame, label_text, - (x_start + 5, y_start + 20), + (x_place_start + 5, y_place_start + 20), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 0), @@ -1054,7 +1089,8 @@ class MediaGrader: # Draw multi-segment timeline self.draw_multi_segment_timeline(combined_frame) - cv2.imshow("Media Grader", combined_frame) + # Maintain aspect ratio when displaying + self.display_with_aspect_ratio(combined_frame) def draw_multi_segment_timeline(self, frame): """Draw timeline showing all segment positions""" @@ -1409,6 +1445,9 @@ class MediaGrader: cv2.namedWindow("Media Grader", cv2.WINDOW_NORMAL) cv2.setMouseCallback("Media Grader", self.mouse_callback) + + # Set initial window size to a reasonable default + cv2.resizeWindow("Media Grader", 1280, 720) while self.media_files and self.current_index < len(self.media_files): current_file = self.media_files[self.current_index]