JuanjoSG5
commited on
Commit
·
2d2877d
1
Parent(s):
f93a0e0
feat: added resize image
Browse files- mcp_server.py +2 -0
- src/utils/change_format.py +26 -13
- src/utils/resize_image.py +56 -0
mcp_server.py
CHANGED
@@ -5,6 +5,7 @@ from src.utils.visualize_image import visualize_base64_image
|
|
5 |
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 |
|
9 |
mcp = FastMCP("Youtube Service")
|
10 |
|
@@ -27,6 +28,7 @@ mcp.add_tool(visualize_base64_image)
|
|
27 |
mcp.add_tool(generate_image)
|
28 |
mcp.add_tool(apply_filter)
|
29 |
mcp.add_tool(add_text_to_image)
|
|
|
30 |
|
31 |
if __name__ == "__main__":
|
32 |
mcp.run()
|
|
|
5 |
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.resize_image import resize_image
|
9 |
|
10 |
mcp = FastMCP("Youtube Service")
|
11 |
|
|
|
28 |
mcp.add_tool(generate_image)
|
29 |
mcp.add_tool(apply_filter)
|
30 |
mcp.add_tool(add_text_to_image)
|
31 |
+
mcp.add_tool(resize_image)
|
32 |
|
33 |
if __name__ == "__main__":
|
34 |
mcp.run()
|
src/utils/change_format.py
CHANGED
@@ -2,8 +2,9 @@ from PIL import Image
|
|
2 |
from io import BytesIO
|
3 |
import requests
|
4 |
import base64
|
|
|
5 |
|
6 |
-
def change_format(
|
7 |
"""
|
8 |
Change the format of an image from a URL to the specified target format.
|
9 |
|
@@ -15,18 +16,30 @@ def change_format(image_url: str, target_format: str) -> str:
|
|
15 |
The image converted to the target format as a base64-encoded string.
|
16 |
"""
|
17 |
|
18 |
-
|
19 |
-
|
|
|
20 |
|
21 |
-
|
22 |
-
|
23 |
|
24 |
# Convert the image to the target format
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2 |
from io import BytesIO
|
3 |
import requests
|
4 |
import base64
|
5 |
+
from typing import Union
|
6 |
|
7 |
+
def change_format(image: Union[str, BytesIO], target_format: str) -> str:
|
8 |
"""
|
9 |
Change the format of an image from a URL to the specified target format.
|
10 |
|
|
|
16 |
The image converted to the target format as a base64-encoded string.
|
17 |
"""
|
18 |
|
19 |
+
if not isinstance(image, BytesIO):
|
20 |
+
response = requests.get(image, timeout=30)
|
21 |
+
response.raise_for_status()
|
22 |
|
23 |
+
# Open the image from bytes
|
24 |
+
img = Image.open(BytesIO(response.content))
|
25 |
|
26 |
# Convert the image to the target format
|
27 |
+
output = BytesIO()
|
28 |
+
img.save(output, format=target_format)
|
29 |
+
output.seek(0)
|
30 |
+
|
31 |
+
# Convert to base64 string for JSON serialization
|
32 |
+
encoded_image = base64.b64encode(output.getvalue()).decode('utf-8')
|
33 |
+
|
34 |
+
return encoded_image # Return base64 encoded string that can be serialized to JSON
|
35 |
+
else:
|
36 |
+
img = Image.open(image)
|
37 |
+
|
38 |
+
output = BytesIO()
|
39 |
+
img.save(output, format=target_format)
|
40 |
+
output.seek(0)
|
41 |
+
|
42 |
+
# Convert to base64 string for JSON serialization
|
43 |
+
encoded_image = base64.b64encode(output.getvalue()).decode('utf-8')
|
44 |
+
|
45 |
+
return encoded_image
|
src/utils/resize_image.py
ADDED
@@ -0,0 +1,56 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from PIL import Image
|
2 |
+
from io import BytesIO
|
3 |
+
import requests
|
4 |
+
import base64
|
5 |
+
from typing import Union, Tuple
|
6 |
+
|
7 |
+
def resize_image(image_input: Union[str, BytesIO], target_size: Tuple[int, int], return_format: str = "base64") -> str:
|
8 |
+
"""
|
9 |
+
Resize an image to the target size while maintaining aspect ratio.
|
10 |
+
|
11 |
+
Args:
|
12 |
+
image_input: URL, file path, base64 string, or BytesIO object
|
13 |
+
target_size: Tuple (width, height) for the target size
|
14 |
+
return_format: Format to return the image in ("base64" or "pil")
|
15 |
+
|
16 |
+
Returns:
|
17 |
+
Base64 encoded string of the resized image or PIL Image object
|
18 |
+
"""
|
19 |
+
# Convert input to PIL Image
|
20 |
+
if isinstance(image_input, str):
|
21 |
+
if image_input.startswith(('http://', 'https://')):
|
22 |
+
# It's a URL
|
23 |
+
response = requests.get(image_input, timeout=10)
|
24 |
+
response.raise_for_status()
|
25 |
+
image = Image.open(BytesIO(response.content))
|
26 |
+
elif image_input.startswith('data:image'):
|
27 |
+
# It's a base64 data URI
|
28 |
+
base64_data = image_input.split(',')[1]
|
29 |
+
image = Image.open(BytesIO(base64.b64decode(base64_data)))
|
30 |
+
elif ';base64,' not in image_input and len(image_input) > 500:
|
31 |
+
# Likely a raw base64 string
|
32 |
+
image = Image.open(BytesIO(base64.b64decode(image_input)))
|
33 |
+
else:
|
34 |
+
# Assume it's a file path
|
35 |
+
image = Image.open(image_input)
|
36 |
+
elif isinstance(image_input, BytesIO):
|
37 |
+
image = Image.open(image_input)
|
38 |
+
else:
|
39 |
+
raise ValueError("Unsupported image input type")
|
40 |
+
|
41 |
+
# Calculate the aspect ratio
|
42 |
+
aspect_ratio = min(target_size[0] / image.width, target_size[1] / image.height)
|
43 |
+
|
44 |
+
# Calculate new size
|
45 |
+
new_size = (int(image.width * aspect_ratio), int(image.height * aspect_ratio))
|
46 |
+
|
47 |
+
# Resize the image using the proper resampling filter
|
48 |
+
resized_image = image.resize(new_size, Image.LANCZOS)
|
49 |
+
|
50 |
+
# Return in requested format
|
51 |
+
if return_format.lower() == "base64":
|
52 |
+
buffer = BytesIO()
|
53 |
+
resized_image.save(buffer, format="PNG")
|
54 |
+
return base64.b64encode(buffer.getvalue()).decode('utf-8')
|
55 |
+
else:
|
56 |
+
return resized_image
|