From b54131e4e77f6586deb6172d79d244b743cda8ed Mon Sep 17 00:00:00 2001 From: PhatPhuckDave Date: Sun, 7 Sep 2025 19:53:20 +0200 Subject: [PATCH] feat(main.py): add functionality to save screenshots with unique filenames and update documentation --- croppa/main.py | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/croppa/main.py b/croppa/main.py index d6cd3fa..24dedfb 100644 --- a/croppa/main.py +++ b/croppa/main.py @@ -168,6 +168,54 @@ class VideoEditor: return f"{base_name}_edited_{next_number:03d}{extension}" + def _get_next_screenshot_filename(self, video_path: Path) -> str: + """Generate the next available screenshot filename: video_frame_00001.jpg, video_frame_00002.jpg, etc.""" + directory = video_path.parent + base_name = video_path.stem + + # Pattern to match existing screenshot files: video_frame_00001.jpg, video_frame_00002.jpg, etc. + pattern = re.compile(rf"^{re.escape(base_name)}_frame_(\d{{5}})\.(jpg|jpeg|png)$") + + existing_numbers = set() + for file_path in directory.iterdir(): + if file_path.is_file(): + match = pattern.match(file_path.name) + if match: + existing_numbers.add(int(match.group(1))) + + # Find the next available number starting from 1 + next_number = 1 + while next_number in existing_numbers: + next_number += 1 + + return f"{base_name}_frame_{next_number:05d}.jpg" + + def save_current_frame(self): + """Save the current frame as a screenshot""" + if self.current_display_frame is None: + print("No frame to save") + return False + + # Generate the next available screenshot filename + screenshot_name = self._get_next_screenshot_filename(self.video_path) + screenshot_path = self.video_path.parent / screenshot_name + + # Apply current transformations (crop, zoom, rotation, brightness/contrast) to the frame + processed_frame = self.apply_crop_zoom_and_rotation(self.current_display_frame.copy()) + + if processed_frame is not None: + # Save the processed frame + success = cv2.imwrite(str(screenshot_path), processed_frame) + if success: + print(f"Screenshot saved: {screenshot_name}") + return True + else: + print(f"Error: Could not save screenshot to {screenshot_path}") + return False + else: + print("Error: Could not process frame for screenshot") + return False + def _get_media_files_from_directory(self, directory: Path) -> List[Path]: """Get all media files (video and image) from a directory, sorted by name""" media_files = set() @@ -1426,6 +1474,7 @@ class VideoEditor: print() print("Other Controls:") print(" Ctrl+Scroll: Zoom in/out") + print(" Shift+S: Save screenshot") if len(self.video_files) > 1: print(" N: Next file") print(" n: Previous file") @@ -1452,6 +1501,7 @@ class VideoEditor: print() print("Other Controls:") print(" Ctrl+Scroll: Zoom in/out") + print(" Shift+S: Save screenshot") print(" 1: Set cut start point") print(" 2: Set cut end point") print(" T: Toggle loop between markers") @@ -1529,6 +1579,8 @@ class VideoEditor: self.playback_speed = max( self.MIN_PLAYBACK_SPEED, self.playback_speed - self.SPEED_INCREMENT ) + elif key == ord("S"): # Shift+S - Save screenshot + self.save_current_frame() elif key == ord("e") or key == ord("E"): # Brightness adjustment: E (increase), Shift+E (decrease) if key == ord("E"):