Skip to content

Conversation

SowmyaKurapati26
Copy link

@SowmyaKurapati26 SowmyaKurapati26 commented Sep 23, 2025

Pull Request for PyVerse 💡

Requesting to submit a pull request to the PyVerse repository.


Issue Title

**🚀 New Advanced Project Proposal: "Image Resizer (GUI)" #1802 **


Info about the Related Issue

Goal:
Create a lightweight Python desktop app to resize images (JPG, PNG, BMP, GIF) by dimensions or percentage scale, with a Tkinter GUI and Pillow for image processing. Also serves as an educational project for learning GUI and image handling in Python.


Name

Sowmya Kurapati


GitHub ID

SowmyaKurapati26


Identify Yourself

Contributing as part of GSSOC25


Closes

Closes: #1802


Changes

  • Added Image Resizer GUI project in Python.
  • Supports custom width/height and percentage scaling.
  • Resized images saved in output/ folder with _resized suffix.
  • Dark-themed Tkinter GUI with error handling.
  • Added README.md with instructions and usage.

Type of Change

  • New feature
  • Documentation update

How Has This Been Tested?

  • Ran app.py locally on Python 3.
  • Verified image resizing works for JPG, PNG, BMP, and GIF.
  • Checked resizing by dimensions and percentage scale.
  • Confirmed resized images saved correctly in output/ folder.
  • Verified GUI responds and errors are handled.

Summary by CodeRabbit

  • New Features
    • Introduced a desktop Image Resizer GUI: select multiple images, resize by exact dimensions or scale, choose output folder, high-quality resizing, preserves extensions, and provides clear success/error messages.
  • Documentation
    • Added README detailing features, requirements, setup, usage steps, and supported formats.
  • Chores
    • Removed the reverse backdoor tool and its execution entry point.

Copy link
Contributor

coderabbitai bot commented Sep 23, 2025

Walkthrough

Adds a new Tkinter-based Image Resizer GUI (with Pillow) and its README under Advanced_Projects/Image_resizer. Removes the reverse backdoor implementation by deleting Cybersecurity_Tools/Reverse_backdoor/backdoor.py.

Changes

Cohort / File(s) Summary of changes
Image Resizer GUI
Advanced_Projects/Image_resizer/app.py, Advanced_Projects/Image_resizer/readme.md
New GUI app to resize images by dimensions or scale using PIL; includes image selection, output folder selection, resize/save logic with validation and feedback. Added README with features, setup, usage, and supported formats.
Reverse Backdoor Removal
Cybersecurity_Tools/Reverse_backdoor/backdoor.py
Deleted the entire reverse backdoor module, removing the Backdoor class, instance creation, and run invocation.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor User
  participant UI as Tkinter UI
  participant App as ImageResizerApp
  participant PIL as Pillow (PIL)
  participant FS as File System
  participant Msg as MessageBox

  User->>UI: Click "Select Images"
  UI->>App: _select_images()
  App->>FS: Open file dialog
  FS-->>App: Image paths
  App-->>Msg: Show selection result

  User->>UI: Enter width/height or scale
  User->>UI: Click "Resize"
  UI->>App: _resize_images()
  App->>App: Validate inputs (paths, dims/scale)

  loop For each selected image
    App->>PIL: Open image
    App->>App: Compute target size
    App->>PIL: Resize (Lanczos)
    App->>FS: Save with "_resized" suffix
  end

  App-->>Msg: Success or error message
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Suggested reviewers

  • UTSAVS26

Poem

Hop hop! I sized the skies, with pixels neat and fair,
From jumbo JPEG mountain to tiny PNG air.
A nibble here, a shrink just there—so tidy, crisp, and wise,
I saved them with a cheeky tag: “_resized” as a prize.
Now off I bounce—next batch to optimize! 🐇✨

Pre-merge checks and finishing touches

❌ Failed checks (2 warnings)
Check name Status Explanation Resolution
Out of Scope Changes Check ⚠️ Warning The PR deletes Cybersecurity_Tools/Reverse_backdoor/backdoor.py (removing the Backdoor class, its instance, and run invocation), which is unrelated to the Image Resizer objectives and therefore constitutes an out-of-scope change that requires justification before merge. Please remove the backdoor deletion from this PR or move that deletion into a separate, documented PR with rationale and maintainer approval; if the removal is intentional, provide a linked issue explaining the reason and include tests or migration steps so maintainers can review the change safely.
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The PR title "Adding Image Resizer Project" is a short, single-sentence summary that clearly identifies the primary change (adding an Image Resizer project); the extra space between "Adding" and "Image" is a minor formatting issue but does not make the title misleading.
Linked Issues Check ✅ Passed The Image Resizer code and README implement the objectives from issue [#1802]: they provide multi-image selection, resizing by width/height or percentage, saving resized files with a _resized suffix into a chosen or auto-created output folder, basic error handling and user feedback, a Tkinter GUI, and support for common formats (JPG/PNG/BMP/GIF), so the coding requirements in the linked issue are met.
✨ Finishing touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Tip

👮 Agentic pre-merge checks are now available in preview!

Pro plan users can now enable pre-merge checks in their settings to enforce checklists before merging PRs.

  • Built-in checks – Quickly apply ready-made checks to enforce title conventions, require pull request descriptions that follow templates, validate linked issues for compliance, and more.
  • Custom agentic checks – Define your own rules using CodeRabbit’s advanced agentic capabilities to enforce organization-specific policies and workflows. For example, you can instruct CodeRabbit’s agent to verify that API documentation is updated whenever API schema files are modified in a PR. Note: Upto 5 custom checks are currently allowed during the preview period. Pricing for this feature will be announced in a few weeks.

Please see the documentation for more information.

Example:

reviews:
  pre_merge_checks:
    custom_checks:
      - name: "Undocumented Breaking Changes"
        mode: "warning"
        instructions: |
          Pass/fail criteria: All breaking changes to public APIs, CLI flags, environment variables, configuration keys, database schemas, or HTTP/GraphQL endpoints must be documented in the "Breaking Change" section of the PR description and in CHANGELOG.md. Exclude purely internal or private changes (e.g., code not exported from package entry points or explicitly marked as internal).

Please share your feedback with us on this Discord post.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

✅ PR validation passed! Syncing labels and assignees from the linked issue...

Copy link

👋 Thank you for opening this pull request! We're excited to review your contribution. Please give us a moment, and we'll get back to you shortly!

Feel free to join our community on Discord to discuss more!

Copy link

✅ PR validation passed! Syncing labels and assignees from the linked issue...

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (7)
Advanced_Projects/Image_resizer/readme.md (3)

21-25: Fix MD040 and correct project path in structure block.

Add fenced-code language and reflect actual repo path to avoid confusion.

-```
+```text
-image_resizer/
+Advanced_Projects/Image_resizer/
 │── app.py           # Full application (GUI + logic)
 └── output/          # Resized images are saved here
-```
+```

42-52: Add “how to run” step.

Include commands to launch the app from the repo path.

 ## 📖 Usage
-
-1. Click **“📂 Select Images”** → choose one or more images.
+Run the app:
+
+```bash
+cd Advanced_Projects/Image_resizer
+python app.py
+```
+
+1. Click **“📂 Select Images”** → choose one or more images.

55-61: Clarify GIF support caveat (animated GIFs).

Current implementation resizes a single frame; animations won’t be preserved.

 - GIF
 +
+- Note: Animated GIFs are not preserved (only the first frame is resized).
Advanced_Projects/Image_resizer/app.py (4)

55-56: Broaden file dialog filter (case variants + All Files).

Improves UX across platforms with case differences.

-            filetypes=[("Image Files", "*.jpg *.jpeg *.png *.bmp *.gif")]
+            filetypes=[
+                ("Image Files", "*.jpg *.jpeg *.png *.bmp *.gif *.JPG *.JPEG *.PNG *.BMP *.GIF"),
+                ("All Files", "*.*"),
+            ]

67-88: Avoid blind except; validate inputs; handle per-image errors without aborting batch.

Current try/except swallows all errors and stops the entire batch on the first failure.

     def _resize_images(self):
         if not self.images:
             messagebox.showerror("Error", "No images selected.")
             return
 
         width = self.width_entry.get()
         height = self.height_entry.get()
         scale = self.scale_entry.get()
 
-        try:
-            width = int(width) if width else None
-            height = int(height) if height else None
-            scale = int(scale) if scale else None
-
-            for img_path in self.images:
-                self._resize_single(img_path, width, height, scale)
-
-            messagebox.showinfo("Success", "Images resized successfully!")
-
-        except Exception as e:
-            messagebox.showerror("Error", str(e))
+        # Parse
+        width = int(width) if width else None
+        height = int(height) if height else None
+        scale = int(scale) if scale else None
+
+        # Basic validation
+        for name, val in (("Width", width), ("Height", height), ("Scale (%)", scale)):
+            if val is not None and val <= 0:
+                messagebox.showerror("Error", f"{name} must be > 0.")
+                return
+
+        successes, failures = 0, 0
+        errors = []
+        for img_path in self.images:
+            try:
+                self._resize_single(img_path, width, height, scale)
+                successes += 1
+            except (UnidentifiedImageError, OSError, ValueError) as e:
+                failures += 1
+                errors.append(f"{os.path.basename(img_path)}: {e}")
+
+        if successes:
+            messagebox.showinfo("Success", f"Resized {successes} of {len(self.images)} image(s).")
+        if failures:
+            preview = "\n".join(errors[:5])
+            suffix = "\n..." if failures > 5 else ""
+            messagebox.showwarning("Some images failed", f"{preview}{suffix}")

89-107: Close files reliably and respect EXIF orientation; use version-safe resample.

Prevents file-handle leaks, rotated outputs, and Pillow version crashes.

-    def _resize_single(self, input_path, width, height, scale):
-        img = Image.open(input_path)
-        orig_width, orig_height = img.size
-
-        if scale:
-            width = int(orig_width * scale / 100)
-            height = int(orig_height * scale / 100)
-        elif width and height:
-            width, height = int(width), int(height)
-        else:
-            raise ValueError("Provide width/height or scale.")
-
-        resized = img.resize((width, height), Image.Resampling.LANCZOS)
-
-        os.makedirs(self.output_folder, exist_ok=True)
-        base, ext = os.path.splitext(os.path.basename(input_path))
-        output_file = os.path.join(self.output_folder, f"{base}_resized{ext}")
-        resized.save(output_file)
+    def _resize_single(self, input_path, width, height, scale):
+        with Image.open(input_path) as img:
+            # Normalize orientation from EXIF before measuring/resizing
+            img = ImageOps.exif_transpose(img)
+            orig_width, orig_height = img.size
+
+            if scale:
+                width = int(orig_width * scale / 100)
+                height = int(orig_height * scale / 100)
+            elif width and height:
+                width, height = int(width), int(height)
+            else:
+                raise ValueError("Provide width/height or scale.")
+
+            resized = img.resize((width, height), RESAMPLE)
+
+            os.makedirs(self.output_folder, exist_ok=True)
+            base, ext = os.path.splitext(os.path.basename(input_path))
+            output_file = os.path.join(self.output_folder, f"{base}_resized{ext}")
+            resized.save(output_file)

93-99: Optionally support single-dimension resize while preserving aspect ratio.

Nice UX improvement: allow width or height alone.

-        elif width and height:
-            width, height = int(width), int(height)
+        elif width and height:
+            width, height = int(width), int(height)
+        elif width or height:
+            # Preserve aspect ratio when one dimension is provided
+            if width:
+                width = int(width)
+                height = int(orig_height * (width / orig_width))
+            else:
+                height = int(height)
+                width = int(orig_width * (height / orig_height))
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 45a0fbe and 843cc3c.

⛔ Files ignored due to path filters (1)
  • Advanced_Projects/Image_resizer/Screenshot 2025-09-24 003634.png is excluded by !**/*.png
📒 Files selected for processing (3)
  • Advanced_Projects/Image_resizer/app.py (1 hunks)
  • Advanced_Projects/Image_resizer/readme.md (1 hunks)
  • Cybersecurity_Tools/Reverse_backdoor/backdoor.py (0 hunks)
💤 Files with no reviewable changes (1)
  • Cybersecurity_Tools/Reverse_backdoor/backdoor.py
🧰 Additional context used
🪛 Ruff (0.13.1)
Advanced_Projects/Image_resizer/app.py

86-86: Do not catch blind exception: Exception

(BLE001)


99-99: Avoid specifying long messages outside the exception class

(TRY003)

🪛 markdownlint-cli2 (0.18.1)
Advanced_Projects/Image_resizer/readme.md

21-21: Fenced code blocks should have a language specified

(MD040, fenced-code-language)

🔇 Additional comments (1)
Advanced_Projects/Image_resizer/app.py (1)

112-115: Main entrypoint LGTM.

Simple, clear startup sequence.

Comment on lines +4 to +7
from PIL import Image


class ImageResizerApp:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Import needed PIL utilities and add LANCZOS fallback for older Pillow.

Prevents runtime errors on Pillow < 9.1.0 and enables safer handling.

-from PIL import Image
+from PIL import Image, UnidentifiedImageError, ImageOps
+
+# Pillow < 9.1.0 fallback
+try:
+    RESAMPLE = Image.Resampling.LANCZOS
+except AttributeError:  # pragma: no cover
+    RESAMPLE = Image.LANCZOS
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
from PIL import Image
class ImageResizerApp:
from PIL import Image, UnidentifiedImageError, ImageOps
# Pillow < 9.1.0 fallback
try:
RESAMPLE = Image.Resampling.LANCZOS
except AttributeError: # pragma: no cover
RESAMPLE = Image.LANCZOS
class ImageResizerApp:
🤖 Prompt for AI Agents
In Advanced_Projects/Image_resizer/app.py around lines 4 to 7, add the missing
PIL utility imports and a compatibility fallback for the LANCZOS resampling
constant: import the required PIL modules (e.g., Image and any utilities you
use) and define a module-level LANCZOS constant using a try/except that prefers
Image.Resampling.LANCZOS and falls back to Image.LANCZOS for older Pillow
versions so resampling calls work across Pillow <9.1.0 and newer releases.

Comment on lines +31 to +38
- Python 3.8+
- [Pillow](https://pypi.org/project/pillow/) (PIL fork, for image processing)

Install dependency:

```bash
pip install pillow
```
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick

Pin minimal Pillow version required by code.

Image.Resampling needs Pillow ≥ 9.1.0.

-```bash
-pip install pillow
-```
+```bash
+pip install "pillow>=9.1.0"
+```
🤖 Prompt for AI Agents
In Advanced_Projects/Image_resizer/readme.md around lines 31 to 38, the
dependency note currently installs Pillow without a version pin even though the
code uses Image.Resampling which requires Pillow >= 9.1.0; update the
installation instruction to pin the minimal required version by replacing the
pip install line with pip install "pillow>=9.1.0" so the correct Pillow API is
available.

@SowmyaKurapati26
Copy link
Author

@UTSAVS26 please review my pr and merge it .

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

🚀 New Advanced Project Proposal: "Image Resizer (GUI)"

1 participant