zoo_mcp 0.9.2__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.
File without changes
@@ -0,0 +1,100 @@
1
+ import base64
2
+ import io
3
+ import tempfile
4
+ from pathlib import Path
5
+
6
+ from mcp.server.fastmcp.utilities.types import Image
7
+ from mcp.types import ImageContent
8
+ from PIL import Image as PILImage
9
+
10
+
11
+ def create_image_collage(image_byte_list: list[bytes]) -> bytes:
12
+ assert len(image_byte_list) == 4, (
13
+ "Exactly 4 images are required to create a 2x2 collage."
14
+ )
15
+
16
+ # Load images
17
+ images = []
18
+ for img_bytes in image_byte_list:
19
+ img = PILImage.open(io.BytesIO(img_bytes))
20
+ img = img.convert("RGB") if img.mode != "RGB" else img
21
+ images.append(img)
22
+
23
+ # Verify all are same size
24
+ widths, heights = zip(*(img.size for img in images))
25
+ if len(set(widths)) > 1 or len(set(heights)) > 1:
26
+ raise ValueError("All images must have the same dimensions.")
27
+
28
+ img_w, img_h = images[0].size
29
+
30
+ # Create blank canvas 2x2
31
+ collage = PILImage.new("RGB", (img_w * 2, img_h * 2))
32
+ positions = [
33
+ (0, 0), # Top-left
34
+ (img_w, 0), # Top-right
35
+ (0, img_h), # Bottom-left
36
+ (img_w, img_h), # Bottom-right
37
+ ]
38
+
39
+ for img, pos in zip(images, positions):
40
+ collage.paste(img, pos)
41
+
42
+ # Scale down by 2x
43
+ collage = collage.resize((img_w, img_h), PILImage.Resampling.LANCZOS)
44
+
45
+ # Save to bytes
46
+ out = io.BytesIO()
47
+ collage.save(out, format="JPEG", quality=95)
48
+ collage_bytes = out.getvalue()
49
+
50
+ # Cleanup
51
+ for img in images:
52
+ img.close()
53
+ collage.close()
54
+ out.close()
55
+
56
+ return collage_bytes
57
+
58
+
59
+ def encode_image(img_bytes: bytes) -> ImageContent:
60
+ """
61
+ Encodes a PIL Image to a format compatible with ImageContent.
62
+ """
63
+ img_obj = Image(data=img_bytes, format="jpeg")
64
+ return img_obj.to_image_content()
65
+
66
+
67
+ def save_image_to_disk(image: ImageContent, output_path: str | None = None) -> str:
68
+ """
69
+ Saves an ImageContent object to disk.
70
+
71
+ Args:
72
+ image: The ImageContent object containing base64-encoded image data.
73
+ output_path: The path where the image should be saved. If a directory is
74
+ provided, a file named 'image.png' will be created in that directory.
75
+ If None, a temporary file will be created.
76
+
77
+ Returns:
78
+ str: The absolute path to the saved image file.
79
+ """
80
+ if output_path is None:
81
+ # Create a temporary file
82
+ _, temp_path = tempfile.mkstemp(suffix=".png")
83
+ path = Path(temp_path)
84
+ else:
85
+ path = Path(output_path)
86
+
87
+ # If path is a directory, create a default filename
88
+ if path.is_dir():
89
+ path = path / "image.png"
90
+
91
+ # Ensure parent directory exists
92
+ path.parent.mkdir(parents=True, exist_ok=True)
93
+
94
+ # Decode base64 data
95
+ image_data = base64.b64decode(image.data)
96
+
97
+ # Write to disk
98
+ path.write_bytes(image_data)
99
+
100
+ return str(path.resolve())