Commit
·
705282e
1
Parent(s):
9b1db12
Added compress function
Browse files- mcp_server.py +2 -0
- src/utils/compress.py +49 -0
mcp_server.py
CHANGED
@@ -6,6 +6,7 @@ from src.utils.generate_image import generate_image
|
|
6 |
from src.utils.apply_filter import apply_filter
|
7 |
from src.utils.add_text import add_text_to_image
|
8 |
from src.utils.describe import describe_image
|
|
|
9 |
|
10 |
mcp = FastMCP("Youtube Service")
|
11 |
|
@@ -29,6 +30,7 @@ mcp.add_tool(visualize_base64_image)
|
|
29 |
mcp.add_tool(generate_image)
|
30 |
mcp.add_tool(apply_filter)
|
31 |
mcp.add_tool(add_text_to_image)
|
|
|
32 |
|
33 |
if __name__ == "__main__":
|
34 |
mcp.run()
|
|
|
6 |
from src.utils.apply_filter import apply_filter
|
7 |
from src.utils.add_text import add_text_to_image
|
8 |
from src.utils.describe import describe_image
|
9 |
+
from src.utils.compress import compress_image
|
10 |
|
11 |
mcp = FastMCP("Youtube Service")
|
12 |
|
|
|
30 |
mcp.add_tool(generate_image)
|
31 |
mcp.add_tool(apply_filter)
|
32 |
mcp.add_tool(add_text_to_image)
|
33 |
+
mcp.add_tool(compress_image)
|
34 |
|
35 |
if __name__ == "__main__":
|
36 |
mcp.run()
|
src/utils/compress.py
ADDED
@@ -0,0 +1,49 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from PIL import Image
|
2 |
+
import os
|
3 |
+
from typing import Literal, Optional
|
4 |
+
|
5 |
+
def compress_image(
|
6 |
+
input_path: str,
|
7 |
+
output_path: str,
|
8 |
+
quality: int = 85,
|
9 |
+
format: Literal["JPEG", "PNG", "WEBP"] = "JPEG",
|
10 |
+
max_width: Optional[int] = None,
|
11 |
+
max_height: Optional[int] = None
|
12 |
+
) -> str:
|
13 |
+
"""
|
14 |
+
Compress an image file.
|
15 |
+
|
16 |
+
Args:
|
17 |
+
input_path: Path to input image
|
18 |
+
output_path: Path for compressed output
|
19 |
+
quality: Compression quality 1-95 (for JPEG/WEBP)
|
20 |
+
format: Output format
|
21 |
+
max_width: Maximum width (optional)
|
22 |
+
max_height: Maximum height (optional)
|
23 |
+
"""
|
24 |
+
try:
|
25 |
+
if not os.path.splitext(output_path)[1]:
|
26 |
+
extension_map = {"JPEG": ".jpg", "PNG": ".png", "WEBP": ".webp"}
|
27 |
+
output_path = output_path + extension_map[format]
|
28 |
+
|
29 |
+
with Image.open(input_path) as img:
|
30 |
+
if format == "JPEG" and img.mode in ("RGBA", "P"):
|
31 |
+
img = img.convert("RGB")
|
32 |
+
|
33 |
+
if max_width or max_height:
|
34 |
+
img.thumbnail((max_width or img.width, max_height or img.height), Image.Resampling.LANCZOS)
|
35 |
+
|
36 |
+
save_kwargs = {"format": format, "optimize": True}
|
37 |
+
if format in ["JPEG", "WEBP"]:
|
38 |
+
save_kwargs["quality"] = quality
|
39 |
+
|
40 |
+
img.save(output_path, **save_kwargs)
|
41 |
+
|
42 |
+
original_size = os.path.getsize(input_path) / 1024 / 1024
|
43 |
+
compressed_size = os.path.getsize(output_path) / 1024 / 1024
|
44 |
+
reduction = (1 - compressed_size/original_size) * 100
|
45 |
+
|
46 |
+
return f"✅ Compressed successfully!\nOriginal: {original_size:.2f}MB → Compressed: {compressed_size:.2f}MB\nReduction: {reduction:.1f}%"
|
47 |
+
|
48 |
+
except Exception as e:
|
49 |
+
return f"❌ Error: {str(e)}"
|