snapforge 0.1.1__py3-none-any.whl
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.
snapforge/__init__.py
ADDED
snapforge/forge.py
ADDED
|
@@ -0,0 +1,89 @@
|
|
|
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}")
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
snapforge/__init__.py,sha256=I2xel16FM40Fc9aWFJRrtJL5ZjQ5IAoTgFyB5gFbV8A,53
|
|
2
|
+
snapforge/forge.py,sha256=-XZ8AVLRWNZnDa7yKP-xWnjt9zU_7wXZThpEcXhMkoc,4261
|
|
3
|
+
snapforge-0.1.1.dist-info/METADATA,sha256=UQ-1_88WsoK4-dJKpKQsxyErEk1CAYx_4RtRhE_PhqQ,219
|
|
4
|
+
snapforge-0.1.1.dist-info/WHEEL,sha256=K260EYznzXsJYBQGqmI8VTxEdiZYNvDZwW9cBh9-_MA,91
|
|
5
|
+
snapforge-0.1.1.dist-info/top_level.txt,sha256=U5q4WCK4d1sn94Rg2dafi2gckV5id8Wt0C5PHysj5a0,10
|
|
6
|
+
snapforge-0.1.1.dist-info/RECORD,,
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
snapforge
|