snapforge 0.1.2__tar.gz → 1.2.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,89 @@
1
+ Metadata-Version: 2.4
2
+ Name: snapforge
3
+ Version: 1.2.0
4
+ Summary: Powerful and fast image editor! 😎
5
+ Author: Ali
6
+ Requires-Python: >=3.7
7
+ Description-Content-Type: text/markdown
8
+ Requires-Dist: Pillow>=9.0.0
9
+
10
+ # 📸 SnapForge
11
+
12
+ [![PyPI version](https://img.shields.io/pypi/v/snapforge.svg)](https://pypi.org/project/snapforge/)
13
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
14
+ [![Python Versions](https://img.shields.io/pypi/pyversions/snapforge.svg)](https://pypi.org/project/snapforge/)
15
+
16
+ **SnapForge** is a lightweight, fast, and intuitive Python library designed for easy image processing tasks. Whether you need to resize, convert, or manipulate images, SnapForge makes it a breeze!
17
+
18
+ ## ✨ Features
19
+
20
+ - 🚀 **Fast & Lightweight**: Minimal overhead for quick image tasks.
21
+ - 🔄 **Format Conversion**: Easily switch between JPEG, PNG, BMP, and more.
22
+ - 📏 **Smart Resizing**: High-quality scaling and resizing capabilities.
23
+ - 🛠️ **Easy API**: Designed with developer experience in mind—simple commands for complex tasks.
24
+ - 🐍 **Pythonic**: Follows Python's best practices for a seamless integration.
25
+
26
+ ## 📦 Installation
27
+
28
+ You can install SnapForge directly from PyPI using `pip`:
29
+ ```bash
30
+ pip install snapforge
31
+
32
+
33
+ 🚀 Quick Start
34
+
35
+ Here is a quick example to get you started with SnapForge:
36
+
37
+ import snapforge
38
+
39
+ # Load an image
40
+ img = snapforge.Snapforge("example.jpg")
41
+
42
+ # Resize the image
43
+ resized_img = img.resize(800,600)
44
+
45
+ # Convert and save the image
46
+ resized_img.convert("PNG").save("example_resized.png")
47
+
48
+ print("Image processed successfully!")
49
+
50
+ ## 🧾 Feature Showcase (Full Reference)
51
+
52
+ Here is the complete list of all available methods in SnapForge:
53
+
54
+ | Category | Method | Description | Example |
55
+ | :--- | :--- | :--- | :--- |
56
+ | **Core** | `.convert(fmt)` | Change image format (e.g., PNG, JPG) | `.convert("PNG")` |
57
+ | | `.resize(w, h)` | Change image dimensions | `.resize(800, 600)` |
58
+ | | `.crop(l, t, r, b)` | Crop image to specific boundaries | `.crop(0, 0, 100, 100)` |
59
+ | | `.rotate(a)` | Rotate image by angle | `.rotate(90)` |
60
+ | | `.optimize(q)` | Set compression quality (1-100) | `.optimize(85)` |
61
+ | | `.save(name)` | Save the final forged image | `.save("result.jpg")` |
62
+ | **Lighting** | `.apply_brightness(f)` | Adjust brightness (factor > 1.0 is brighter) | `.apply_brightness(1.2)` |
63
+ | | `.apply_contrast(f)` | Adjust contrast (factor > 1.0 is higher) | `.apply_contrast(1.5)` |
64
+ | **Filters** | `.apply_sepia()` | Apply a classic vintage sepia effect | `.apply_sepia()` |
65
+ | | `.apply_grayscale(f)` | Convert to black & white (0.0 to 1.0) | `.apply_grayscale(1.0)` |
66
+ | | `.apply_blur(r)` | Apply Gaussian blur with radius r | `.apply_blur(5.0)` |
67
+ | | `.apply_sharpen()` | Enhance image sharpness/clarity | `.apply_sharpen()` |
68
+ | | `.apply_camscanner()`| Apply document scanner effect (B&W/Threshold) | `.apply_camscanner()` |
69
+ | **Extras** | `.flip(dir)` | Flip image (horizontal or vertical) | `.flip("horizontal")` |
70
+ | | `.add_watermark(p)` | Add a watermark image | `.add_watermark("logo.png")` |
71
+
72
+
73
+ 🛠️ Requirements
74
+
75
+ Python: 3.7 or higher
76
+ Dependencies: Pillow
77
+
78
+ 🤝 Contributing
79
+
80
+ Contributions are what make the open-source community such an amazing place to learn, inspire, and create. Any contributions you make are greatly appreciated.
81
+
82
+ 📜 License
83
+
84
+ Distributed under the MIT License.
85
+
86
+ 👤 Author
87
+
88
+ Ali.Shm
89
+ Project Maintainer
@@ -0,0 +1,80 @@
1
+ # 📸 SnapForge
2
+
3
+ [![PyPI version](https://img.shields.io/pypi/v/snapforge.svg)](https://pypi.org/project/snapforge/)
4
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
5
+ [![Python Versions](https://img.shields.io/pypi/pyversions/snapforge.svg)](https://pypi.org/project/snapforge/)
6
+
7
+ **SnapForge** is a lightweight, fast, and intuitive Python library designed for easy image processing tasks. Whether you need to resize, convert, or manipulate images, SnapForge makes it a breeze!
8
+
9
+ ## ✨ Features
10
+
11
+ - 🚀 **Fast & Lightweight**: Minimal overhead for quick image tasks.
12
+ - 🔄 **Format Conversion**: Easily switch between JPEG, PNG, BMP, and more.
13
+ - 📏 **Smart Resizing**: High-quality scaling and resizing capabilities.
14
+ - 🛠️ **Easy API**: Designed with developer experience in mind—simple commands for complex tasks.
15
+ - 🐍 **Pythonic**: Follows Python's best practices for a seamless integration.
16
+
17
+ ## 📦 Installation
18
+
19
+ You can install SnapForge directly from PyPI using `pip`:
20
+ ```bash
21
+ pip install snapforge
22
+
23
+
24
+ 🚀 Quick Start
25
+
26
+ Here is a quick example to get you started with SnapForge:
27
+
28
+ import snapforge
29
+
30
+ # Load an image
31
+ img = snapforge.Snapforge("example.jpg")
32
+
33
+ # Resize the image
34
+ resized_img = img.resize(800,600)
35
+
36
+ # Convert and save the image
37
+ resized_img.convert("PNG").save("example_resized.png")
38
+
39
+ print("Image processed successfully!")
40
+
41
+ ## 🧾 Feature Showcase (Full Reference)
42
+
43
+ Here is the complete list of all available methods in SnapForge:
44
+
45
+ | Category | Method | Description | Example |
46
+ | :--- | :--- | :--- | :--- |
47
+ | **Core** | `.convert(fmt)` | Change image format (e.g., PNG, JPG) | `.convert("PNG")` |
48
+ | | `.resize(w, h)` | Change image dimensions | `.resize(800, 600)` |
49
+ | | `.crop(l, t, r, b)` | Crop image to specific boundaries | `.crop(0, 0, 100, 100)` |
50
+ | | `.rotate(a)` | Rotate image by angle | `.rotate(90)` |
51
+ | | `.optimize(q)` | Set compression quality (1-100) | `.optimize(85)` |
52
+ | | `.save(name)` | Save the final forged image | `.save("result.jpg")` |
53
+ | **Lighting** | `.apply_brightness(f)` | Adjust brightness (factor > 1.0 is brighter) | `.apply_brightness(1.2)` |
54
+ | | `.apply_contrast(f)` | Adjust contrast (factor > 1.0 is higher) | `.apply_contrast(1.5)` |
55
+ | **Filters** | `.apply_sepia()` | Apply a classic vintage sepia effect | `.apply_sepia()` |
56
+ | | `.apply_grayscale(f)` | Convert to black & white (0.0 to 1.0) | `.apply_grayscale(1.0)` |
57
+ | | `.apply_blur(r)` | Apply Gaussian blur with radius r | `.apply_blur(5.0)` |
58
+ | | `.apply_sharpen()` | Enhance image sharpness/clarity | `.apply_sharpen()` |
59
+ | | `.apply_camscanner()`| Apply document scanner effect (B&W/Threshold) | `.apply_camscanner()` |
60
+ | **Extras** | `.flip(dir)` | Flip image (horizontal or vertical) | `.flip("horizontal")` |
61
+ | | `.add_watermark(p)` | Add a watermark image | `.add_watermark("logo.png")` |
62
+
63
+
64
+ 🛠️ Requirements
65
+
66
+ Python: 3.7 or higher
67
+ Dependencies: Pillow
68
+
69
+ 🤝 Contributing
70
+
71
+ Contributions are what make the open-source community such an amazing place to learn, inspire, and create. Any contributions you make are greatly appreciated.
72
+
73
+ 📜 License
74
+
75
+ Distributed under the MIT License.
76
+
77
+ 👤 Author
78
+
79
+ Ali.Shm
80
+ Project Maintainer
@@ -4,12 +4,12 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "snapforge"
7
- version = "0.1.2"
7
+ version = "1.2.0"
8
8
  description = "Powerful and fast image editor! 😎"
9
9
  authors = [
10
10
  { name="Ali"},
11
11
  ]
12
- readme = "README.md"
12
+ readme = {file = "README.md", content-type = "text/markdown"}
13
13
  requires-python = ">=3.7"
14
14
  dependencies = [
15
15
  "Pillow>=9.0.0",
@@ -1,3 +1,3 @@
1
1
  from .forge import SnapForge
2
2
 
3
- __version__ = "0.1.2"
3
+ __version__ = "1.2.0"
@@ -0,0 +1,223 @@
1
+ from PIL import Image, ImageEnhance, ImageOps, ImageFilter
2
+ import os
3
+ import requests
4
+ import threading
5
+ from datetime import datetime
6
+ from packaging import version
7
+
8
+ class SnapForgeUpdater:
9
+ def __init__(self, package_name: str, current_version: str):
10
+ self.package_name = package_name
11
+ self.current_version = current_version
12
+ self.api_url = f"https://pypi.org/pypi/{package_name}/json"
13
+
14
+ def _check_logic(self):
15
+ """Perform the update check in the background."""
16
+ try:
17
+ response = requests.get(self.api_url, timeout=5)
18
+ if response.status_code != 200:
19
+ return
20
+
21
+ data = response.json()
22
+ latest_version = data["info"]["version"]
23
+
24
+ if version.parse(latest_version) > version.parse(self.current_version):
25
+ latest_release_data = data["releases"][latest_version][0]
26
+ iso_time = latest_release_data["upload_time_iso_8601"]
27
+
28
+ dt_object = datetime.fromisoformat(iso_time.replace('Z', '+00:00'))
29
+ formatted_time = dt_object.strftime('%Y-%m-%d %H:%M:%S')
30
+
31
+ self._notify_user(latest_version, formatted_time)
32
+
33
+ except Exception:
34
+ pass
35
+
36
+ def _notify_user(self, latest_version, upload_time):
37
+ """Display the update notification to the user."""
38
+ print("\n" + "="*50)
39
+ print(f"🚀 [SnapForge] NEW UPDATE AVAILABLE!")
40
+ print(f"✨ Latest Version: {latest_version}")
41
+ print(f"📅 Released on: {upload_time} (UTC)")
42
+ print(f"🛠️ Your Version: {self.current_version}")
43
+ print(f"👉 Run: pip install --upgrade {self.package_name}")
44
+ print("="*50 + "\n")
45
+
46
+ def start_check(self):
47
+ """Initialize the update check in a separate thread."""
48
+ thread = threading.Thread(target=self._check_logic, daemon=True)
49
+ thread.start()
50
+
51
+ class SnapForge:
52
+ __version__ = "1.2.0"
53
+
54
+ def __init__(self, image_path: str):
55
+ """ 😎 Load your image and get ready for the magic! 😎 """
56
+ updater = SnapForgeUpdater("snapforge", self.__version__)
57
+ updater.start_check()
58
+
59
+ print(f"📸 SnapForge initialized (v{self.__version__})")
60
+ if not os.path.exists(image_path):
61
+ raise FileNotFoundError(f"❌ Error: The specified file path does not exist: '{image_path}'")
62
+
63
+ try:
64
+ self.image = Image.open(image_path).convert("RGB")
65
+ self.original_format = self.image.format
66
+ self.target_format = self.original_format if self.original_format else "JPEG"
67
+ self.quality = 85
68
+ print(f"🚀 Success: Image loaded successfully. Original format: {self.target_format}")
69
+ except Exception as e:
70
+ raise IOError(f"❌ Error: Failed to open the image. Details: {e}")
71
+
72
+ def convert(self, new_format: str):
73
+ """ 😎 Change the format! 😎 """
74
+ self.target_format = new_format.upper()
75
+ print(f"🔄 Format set to: {self.target_format}")
76
+ return self
77
+
78
+ def resize(self, width: int, height: int):
79
+ """ 😎 Shrink it or expand it! 😎 """
80
+ if width <= 0 or height <= 0:
81
+ raise ValueError("❌ Error: Width and height must be positive integers.")
82
+ self.image = self.image.resize((width, height), Image.Resampling.LANCZOS)
83
+ print(f"📏 Success: Image resized to {width}x{height}")
84
+ return self
85
+
86
+ def optimize(self, quality: int = 85):
87
+ """ 😎 Make it lightweight! 😎 """
88
+ if not (1 <= quality <= 100):
89
+ raise ValueError("❌ Error: Quality must be between 1 and 100.")
90
+ self.quality = quality
91
+ print(f"✨ Success: Optimization mode enabled (Quality: {quality}%)")
92
+ return self
93
+
94
+ # --- NEW FEATURES ADDED BELOW ---
95
+
96
+ def apply_brightness(self, factor: float):
97
+ """ 😎 Light it up or dim it down! 😎
98
+ factor: 1.0 is original, < 1.0 is darker, > 1.0 is brighter
99
+ """
100
+ enhancer = ImageEnhance.Brightness(self.image)
101
+ self.image = enhancer.enhance(factor)
102
+ print(f"☀️ Success: Brightness adjusted by factor {factor}")
103
+ return self
104
+
105
+ def apply_contrast(self, factor: float):
106
+ """ 😎 Pop those colors! 😎
107
+ factor: 1.0 is original, < 1.0 is lower contrast, > 1.0 is higher contrast
108
+ """
109
+ enhancer = ImageEnhance.Contrast(self.image)
110
+ self.image = enhancer.enhance(factor)
111
+ print(f"🌗 Success: Contrast adjusted by factor {factor}")
112
+ return self
113
+
114
+ def apply_sepia(self):
115
+ """ 😎 Just like old cameras! (Sepia Filter) 😎 """
116
+ # Applying sepia via color transformation
117
+ width, height = self.image.size
118
+ pixels = self.image.load()
119
+ for py in range(height):
120
+ for px in range(width):
121
+ r, g, b = pixels[px, py]
122
+ # Standard Sepia formula
123
+ tr = int(0.393 * r + 0.769 * g + 0.189 * b)
124
+ tg = int(0.349 * r + 0.686 * g + 0.168 * b)
125
+ tb = int(0.272 * r + 0.534 * g + 0.131 * b)
126
+ pixels[px, py] = (min(tr, 255), min(tg, 255), min(tb, 255))
127
+ print(f"📜 Success: Sepia effect applied!")
128
+ return self
129
+
130
+ def apply_blur(self, radius: float):
131
+ """ 😎 Make it dreamy! 😎 """
132
+ self.image = self.image.filter(ImageFilter.GaussianBlur(radius))
133
+ print(f"☁️ Success: Blur applied with radius {radius}")
134
+ return self
135
+
136
+ def apply_sharpen(self):
137
+ """ 😎 Make it crisp! 😎 """
138
+ self.image = self.image.filter(ImageFilter.SHARPEN)
139
+ print(f"🎯 Success: Image sharpened!")
140
+ return self
141
+
142
+ # --- END OF NEW FEATURES ---
143
+
144
+ def apply_grayscale(self, factor: float = 1.0):
145
+ """ 😎 Make it moody! 😎 """
146
+ if not (0.0 <= factor <= 1.0):
147
+ raise ValueError("❌ Error: Factor must be between 0.0 and 1.0")
148
+ grayscale_image = ImageOps.grayscale(self.image).convert("RGB")
149
+ self.image = Image.blend(self.image, grayscale_image, factor)
150
+ print(f"🌑 Success: Grayscale effect applied with factor {factor}")
151
+ return self
152
+
153
+ def add_watermark(self, watermark_path: str, position: tuple = (0, 0), opacity: float = 0.5):
154
+ """ 😎 Put your signature! 😎 """
155
+ if not os.path.exists(watermark_path):
156
+ raise FileNotFoundError(f"❌ Error: Watermark file not found at: '{watermark_path}'")
157
+ try:
158
+ watermark = Image.open(watermark_path).convert("RGBA")
159
+ alpha = watermark.split()[3]
160
+ alpha = ImageEnhance.Brightness(alpha).enhance(opacity)
161
+ watermark.putalpha(alpha)
162
+ self.image.paste(watermark, position, watermark)
163
+ print(f"🛡️ Success: Watermark applied at position {position}")
164
+ except Exception as e:
165
+ raise RuntimeError(f"❌ Error: Failed to apply watermark. Details: {e}")
166
+ return self
167
+
168
+ def save(self, output_name: str):
169
+ """ 😎 The moment of truth! 😎 """
170
+ try:
171
+ if not output_name.lower().endswith(f".{self.target_format.lower()}"):
172
+ output_name = f"{output_name}.{self.target_format.lower()}"
173
+
174
+ save_kwargs = {"optimize": True}
175
+ if self.target_format in ["JPEG", "JPG"]:
176
+ save_kwargs["quality"] = self.quality
177
+
178
+ self.image.save(output_name, **save_kwargs)
179
+ print(f"🎉 Success: Image forged and saved as '{output_name}' 🎉")
180
+ return output_name
181
+ except Exception as e:
182
+ raise IOError(f"❌ Error: Failed to save the image. Details: {e}")
183
+
184
+ def flip(self, direction: str = "horizontal"):
185
+ """ 😎 Flip the image! direction: 'horizontal' or 'vertical' 😎 """
186
+ if direction.lower() == "horizontal":
187
+ self.image = self.image.transpose(Image.FLIP_LEFT_RIGHT)
188
+ elif direction.lower() == "vertical":
189
+ self.image = self.image.transpose(Image.FLIP_TOP_BOTTOM)
190
+ else:
191
+ raise ValueError("❌ Error: Direction must be 'horizontal' or 'vertical'.")
192
+ print(f"🔄 Success: Image flipped {direction}ly")
193
+ return self
194
+
195
+ def apply_camscanner(self):
196
+ """ 😎 Make it look like a scanned document! 😎 """
197
+
198
+ self.image = self.image.convert("L")
199
+
200
+ threshold = 150
201
+ self.image = self.image.point(lambda p: 255 if p > threshold else 0)
202
+
203
+ self.image = self.image.convert("RGB")
204
+
205
+ print(f"📄 Success: CamScanner effect applied!")
206
+ return self
207
+
208
+ def rotate(self, angle: float, expand: bool = True):
209
+ """ 😎 Rotate the image by any angle! 😎
210
+ angle: degrees (positive is counter-clockwise)
211
+ expand: If True, expands the output image to fit the rotated image.
212
+ """
213
+ self.image = self.image.rotate(angle, expand=expand)
214
+ print(f"🔄 Success: Image rotated by {angle} degrees")
215
+ return self
216
+
217
+ def crop(self, left: int, top: int, right: int, bottom: int):
218
+ """ 😎 Cut out the unwanted parts! 😎
219
+ Arguments define the box to keep.
220
+ """
221
+ self.image = self.image.crop((left, top, right, bottom))
222
+ print(f"✂️ Success: Image cropped to ({left}, {top}, {right}, {bottom})")
223
+ return self
@@ -0,0 +1,89 @@
1
+ Metadata-Version: 2.4
2
+ Name: snapforge
3
+ Version: 1.2.0
4
+ Summary: Powerful and fast image editor! 😎
5
+ Author: Ali
6
+ Requires-Python: >=3.7
7
+ Description-Content-Type: text/markdown
8
+ Requires-Dist: Pillow>=9.0.0
9
+
10
+ # 📸 SnapForge
11
+
12
+ [![PyPI version](https://img.shields.io/pypi/v/snapforge.svg)](https://pypi.org/project/snapforge/)
13
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
14
+ [![Python Versions](https://img.shields.io/pypi/pyversions/snapforge.svg)](https://pypi.org/project/snapforge/)
15
+
16
+ **SnapForge** is a lightweight, fast, and intuitive Python library designed for easy image processing tasks. Whether you need to resize, convert, or manipulate images, SnapForge makes it a breeze!
17
+
18
+ ## ✨ Features
19
+
20
+ - 🚀 **Fast & Lightweight**: Minimal overhead for quick image tasks.
21
+ - 🔄 **Format Conversion**: Easily switch between JPEG, PNG, BMP, and more.
22
+ - 📏 **Smart Resizing**: High-quality scaling and resizing capabilities.
23
+ - 🛠️ **Easy API**: Designed with developer experience in mind—simple commands for complex tasks.
24
+ - 🐍 **Pythonic**: Follows Python's best practices for a seamless integration.
25
+
26
+ ## 📦 Installation
27
+
28
+ You can install SnapForge directly from PyPI using `pip`:
29
+ ```bash
30
+ pip install snapforge
31
+
32
+
33
+ 🚀 Quick Start
34
+
35
+ Here is a quick example to get you started with SnapForge:
36
+
37
+ import snapforge
38
+
39
+ # Load an image
40
+ img = snapforge.Snapforge("example.jpg")
41
+
42
+ # Resize the image
43
+ resized_img = img.resize(800,600)
44
+
45
+ # Convert and save the image
46
+ resized_img.convert("PNG").save("example_resized.png")
47
+
48
+ print("Image processed successfully!")
49
+
50
+ ## 🧾 Feature Showcase (Full Reference)
51
+
52
+ Here is the complete list of all available methods in SnapForge:
53
+
54
+ | Category | Method | Description | Example |
55
+ | :--- | :--- | :--- | :--- |
56
+ | **Core** | `.convert(fmt)` | Change image format (e.g., PNG, JPG) | `.convert("PNG")` |
57
+ | | `.resize(w, h)` | Change image dimensions | `.resize(800, 600)` |
58
+ | | `.crop(l, t, r, b)` | Crop image to specific boundaries | `.crop(0, 0, 100, 100)` |
59
+ | | `.rotate(a)` | Rotate image by angle | `.rotate(90)` |
60
+ | | `.optimize(q)` | Set compression quality (1-100) | `.optimize(85)` |
61
+ | | `.save(name)` | Save the final forged image | `.save("result.jpg")` |
62
+ | **Lighting** | `.apply_brightness(f)` | Adjust brightness (factor > 1.0 is brighter) | `.apply_brightness(1.2)` |
63
+ | | `.apply_contrast(f)` | Adjust contrast (factor > 1.0 is higher) | `.apply_contrast(1.5)` |
64
+ | **Filters** | `.apply_sepia()` | Apply a classic vintage sepia effect | `.apply_sepia()` |
65
+ | | `.apply_grayscale(f)` | Convert to black & white (0.0 to 1.0) | `.apply_grayscale(1.0)` |
66
+ | | `.apply_blur(r)` | Apply Gaussian blur with radius r | `.apply_blur(5.0)` |
67
+ | | `.apply_sharpen()` | Enhance image sharpness/clarity | `.apply_sharpen()` |
68
+ | | `.apply_camscanner()`| Apply document scanner effect (B&W/Threshold) | `.apply_camscanner()` |
69
+ | **Extras** | `.flip(dir)` | Flip image (horizontal or vertical) | `.flip("horizontal")` |
70
+ | | `.add_watermark(p)` | Add a watermark image | `.add_watermark("logo.png")` |
71
+
72
+
73
+ 🛠️ Requirements
74
+
75
+ Python: 3.7 or higher
76
+ Dependencies: Pillow
77
+
78
+ 🤝 Contributing
79
+
80
+ Contributions are what make the open-source community such an amazing place to learn, inspire, and create. Any contributions you make are greatly appreciated.
81
+
82
+ 📜 License
83
+
84
+ Distributed under the MIT License.
85
+
86
+ 👤 Author
87
+
88
+ Ali.Shm
89
+ Project Maintainer
@@ -1,3 +1,4 @@
1
+ README.md
1
2
  pyproject.toml
2
3
  snapforge/__init__.py
3
4
  snapforge/forge.py
snapforge-0.1.2/PKG-INFO DELETED
@@ -1,8 +0,0 @@
1
- Metadata-Version: 2.4
2
- Name: snapforge
3
- Version: 0.1.2
4
- Summary: Powerful and fast image editor! 😎
5
- Author: Ali
6
- Requires-Python: >=3.7
7
- Description-Content-Type: text/markdown
8
- Requires-Dist: Pillow>=9.0.0
@@ -1,89 +0,0 @@
1
- from PIL import Image, ImageEnhance, ImageOps
2
- import os
3
-
4
- class SnapForge:
5
- """ 😎 Welcome to SnapForge! The ultimate tool to forge your images into greatness! 😎 """
6
-
7
- def __init__(self, image_path: str):
8
- """ 😎 Load your image and get ready for the magic! 😎 """
9
- if not os.path.exists(image_path):
10
- raise FileNotFoundError(f"❌ Error: The specified file path does not exist: '{image_path}'")
11
-
12
- try:
13
- self.image = Image.open(image_path).convert("RGB") # تبدیل به RGB برای سازگاری بهتر
14
- self.original_format = self.image.format
15
- self.target_format = self.original_format if self.original_format else "JPEG"
16
- print(f"🚀 Success: Image loaded successfully. Original format: {self.target_format}")
17
- except Exception as e:
18
- raise IOError(f"❌ Error: Failed to open the image. Details: {e}")
19
-
20
- def convert(self, new_format: str):
21
- """ 😎 Change the format! 😎 """
22
- self.target_format = new_format.upper()
23
- print(f"🔄 Format set to: {self.target_format}")
24
- return self
25
-
26
- def resize(self, width: int, height: int):
27
- """ 😎 Shrink it or expand it! 😎 """
28
- if width <= 0 or height <= 0:
29
- raise ValueError("❌ Error: Width and height must be positive integers.")
30
- self.image = self.image.resize((width, height), Image.Resampling.LANCZOS)
31
- print(f"📏 Success: Image resized to {width}x{height}")
32
- return self
33
-
34
- def optimize(self, quality: int = 85):
35
- """ 😎 Make it lightweight! 😎 """
36
- if not (1 <= quality <= 100):
37
- raise ValueError("❌ Error: Quality must be between 1 and 100.")
38
- self.quality = quality
39
- print(f"✨ Success: Optimization mode enabled (Quality: {quality}%)")
40
- return self
41
-
42
- def apply_grayscale(self, factor: float = 1.0):
43
- """
44
- 😎 Make it moody! 😎
45
- factor: 0.0 (full color) to 1.0 (full black & white)
46
- """
47
- if not (0.0 <= factor <= 1.0):
48
- raise ValueError("❌ Error: Factor must be between 0.0 and 1.0")
49
-
50
- # ایجاد نسخه سیاه و سفید
51
- grayscale_image = ImageOps.grayscale(self.image).convert("RGB")
52
-
53
- # ترکیب تصویر اصلی با تصویر سیاه و سفید بر اساس فاکتور
54
- # فرمول: Result = Image * (1 - factor) + Grayscale * factor
55
- self.image = Image.blend(self.image, grayscale_image, factor)
56
-
57
- print(f"🌑 Success: Grayscale effect applied with factor {factor}")
58
- return self
59
-
60
- def add_watermark(self, watermark_path: str, position: tuple = (0, 0), opacity: float = 0.5):
61
- """ 😎 Put your signature! 😎 """
62
- if not os.path.exists(watermark_path):
63
- raise FileNotFoundError(f"❌ Error: Watermark file not found at: '{watermark_path}'")
64
- try:
65
- watermark = Image.open(watermark_path).convert("RGBA")
66
- alpha = watermark.split()[3]
67
- alpha = ImageEnhance.Brightness(alpha).enhance(opacity)
68
- watermark.putalpha(alpha)
69
- self.image.paste(watermark, position, watermark)
70
- print(f"🛡️ Success: Watermark applied at position {position}")
71
- except Exception as e:
72
- raise RuntimeError(f"❌ Error: Failed to apply watermark. Details: {e}")
73
- return self
74
-
75
- def save(self, output_name: str):
76
- """ 😎 The moment of truth! 😎 """
77
- try:
78
- if not output_name.lower().endswith(f".{self.target_format.lower()}"):
79
- output_name = f"{output_name}.{self.target_format.lower()}"
80
-
81
- save_kwargs = {"optimize": True}
82
- if self.target_format in ["JPEG", "JPG"]:
83
- save_kwargs["quality"] = getattr(self, 'quality', 85)
84
-
85
- self.image.save(output_name, **save_kwargs)
86
- print(f"🎉 Success: Image forged and saved as '{output_name}' 🎉")
87
- return output_name
88
- except Exception as e:
89
- raise IOError(f"❌ Error: Failed to save the image. Details: {e}")
@@ -1,8 +0,0 @@
1
- Metadata-Version: 2.4
2
- Name: snapforge
3
- Version: 0.1.2
4
- Summary: Powerful and fast image editor! 😎
5
- Author: Ali
6
- Requires-Python: >=3.7
7
- Description-Content-Type: text/markdown
8
- Requires-Dist: Pillow>=9.0.0
File without changes