Skip to main content
Glama
duke0317

Image Processing MCP Server

by duke0317

add_shadow

Adds customizable shadow effects to images by adjusting color, offset, blur, and opacity to create depth and visual separation.

Instructions

为图片添加阴影效果

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
image_sourceYes图片源,可以是文件路径或base64编码的图片数据
shadow_colorNo阴影颜色,十六进制格式如 #808080(灰色)#808080
shadow_offset_xNo阴影水平偏移(像素),正值向右,负值向左
shadow_offset_yNo阴影垂直偏移(像素),正值向下,负值向上
shadow_blurNo阴影模糊半径(像素)
shadow_opacityNo阴影不透明度,范围 0.0-1.0
output_formatNo输出格式:PNG、JPEG、WEBP 等PNG

Implementation Reference

  • Core handler function implementing the add_shadow tool logic: validates parameters, loads image, creates shadow layer from alpha channel, applies blur and offset, composites with original image, outputs base64 result.
    async def add_shadow(arguments: Dict[str, Any]) -> List[TextContent]:
        """
        为图片添加阴影效果
        
        Args:
            arguments: 包含图片源和阴影参数的字典
            
        Returns:
            List[TextContent]: 处理结果
        """
        try:
            # 参数验证
            image_source = arguments.get("image_source")
            ensure_valid_image_source(image_source)
            
            shadow_color = arguments.get("shadow_color", "#808080")
            shadow_offset_x = arguments.get("shadow_offset_x", 5)
            shadow_offset_y = arguments.get("shadow_offset_y", 5)
            shadow_blur = arguments.get("shadow_blur", 5)
            shadow_opacity = arguments.get("shadow_opacity", 0.5)
            output_format = arguments.get("output_format", DEFAULT_IMAGE_FORMAT)
            
            # 验证参数
            validate_color_hex(shadow_color)
            validate_numeric_range(shadow_offset_x, -50, 50, "shadow_offset_x")
            validate_numeric_range(shadow_offset_y, -50, 50, "shadow_offset_y")
            validate_numeric_range(shadow_blur, 0, 20, "shadow_blur")
            validate_numeric_range(shadow_opacity, 0.0, 1.0, "shadow_opacity")
            
            # 加载图片
            processor = ImageProcessor()
            image = processor.load_image(image_source)
            
            # 转换为RGBA模式
            if image.mode != "RGBA":
                image = image.convert("RGBA")
            
            # 计算新图片尺寸(考虑阴影偏移和模糊)
            margin = shadow_blur + max(abs(shadow_offset_x), abs(shadow_offset_y))
            new_width = image.width + 2 * margin
            new_height = image.height + 2 * margin
            
            # 创建带阴影的新图片
            result_image = Image.new("RGBA", (new_width, new_height), (0, 0, 0, 0))
            
            # 创建阴影
            shadow_rgb = tuple(int(shadow_color[i:i+2], 16) for i in (1, 3, 5))
            shadow_alpha = int(255 * shadow_opacity)
            
            # 创建阴影图层
            shadow_layer = Image.new("RGBA", image.size, (0, 0, 0, 0))
            shadow_pixels = shadow_layer.load()
            image_pixels = image.load()
            
            # 根据原图的alpha通道创建阴影
            for y in range(image.height):
                for x in range(image.width):
                    r, g, b, a = image_pixels[x, y]
                    if a > 0:
                        shadow_pixels[x, y] = shadow_rgb + (min(a, shadow_alpha),)
            
            # 应用模糊
            if shadow_blur > 0:
                shadow_layer = shadow_layer.filter(ImageFilter.GaussianBlur(radius=shadow_blur))
            
            # 计算阴影位置
            shadow_x = margin + shadow_offset_x
            shadow_y = margin + shadow_offset_y
            
            # 粘贴阴影
            result_image.paste(shadow_layer, (shadow_x, shadow_y), shadow_layer)
            
            # 粘贴原图片
            image_x = margin
            image_y = margin
            result_image.paste(image, (image_x, image_y), image)
            
            # 转换为base64
            output_info = processor.output_image(result_image, "border", output_format)
            
            return [TextContent(
                type="text",
                text=json.dumps({
                    "success": True,
                    "message": "成功添加阴影效果",
                    "data": {
                        **output_info,
                        "metadata": {
                            "original_size": f"{image.width}x{image.height}",
                            "new_size": f"{result_image.width}x{result_image.height}",
                            "shadow_color": shadow_color,
                            "shadow_offset": f"({shadow_offset_x}, {shadow_offset_y})",
                            "shadow_blur": shadow_blur,
                            "shadow_opacity": shadow_opacity,
                            "format": output_format
                        }
                    }
                }, ensure_ascii=False)
            )]
            
        except ValidationError as e:
            return [TextContent(
                type="text",
                text=json.dumps({
                    "success": False,
                    "error": f"参数验证失败: {str(e)}"
                }, ensure_ascii=False)
            )]
        except Exception as e:
            return [TextContent(
                type="text",
                text=json.dumps({
                    "success": False,
                    "error": f"添加阴影失败: {str(e)}"
                }, ensure_ascii=False)
            )]
  • main.py:542-569 (registration)
    MCP tool registration for 'add_shadow': defines input schema via Annotated parameters and wraps the call to the effects handler.
    @mcp.tool()
    def add_shadow(
        image_source: Annotated[str, Field(description="图片源,可以是文件路径或base64编码的图片数据")],
        shadow_color: Annotated[str, Field(description="阴影颜色,十六进制格式如 #808080(灰色)", default="#808080")],
        shadow_offset_x: Annotated[int, Field(description="阴影水平偏移(像素),正值向右,负值向左", default=5)],
        shadow_offset_y: Annotated[int, Field(description="阴影垂直偏移(像素),正值向下,负值向上", default=5)],
        shadow_blur: Annotated[int, Field(description="阴影模糊半径(像素)", ge=0, default=5)],
        shadow_opacity: Annotated[float, Field(description="阴影不透明度,范围 0.0-1.0", ge=0.0, le=1.0, default=0.5)],
        output_format: Annotated[str, Field(description="输出格式:PNG、JPEG、WEBP 等", default="PNG")]
    ) -> str:
        """为图片添加阴影效果"""
        try:
            arguments = {
                "image_source": image_source,
                "shadow_color": shadow_color,
                "shadow_offset_x": shadow_offset_x,
                "shadow_offset_y": shadow_offset_y,
                "shadow_blur": shadow_blur,
                "shadow_opacity": shadow_opacity,
                "output_format": output_format
            }
            result = safe_run_async(effects_add_shadow(arguments))
            return result[0].text
        except Exception as e:
            return json.dumps({
                "success": False,
                "error": f"添加阴影失败: {str(e)}"
            }, ensure_ascii=False, indent=2)
  • JSON schema definition for the add_shadow tool input parameters in get_effect_tools().
    Tool(
        name="add_shadow",
        description="为图片添加阴影效果",
        inputSchema={
            "type": "object",
            "properties": {
                "image_source": {
                    "type": "string",
                    "description": "图片源(文件路径或base64编码)"
                },
                "shadow_color": {
                    "type": "string",
                    "description": "阴影颜色(十六进制格式)",
                    "default": "#808080"
                },
                "shadow_offset_x": {
                    "type": "integer",
                    "description": "阴影X轴偏移(像素)",
                    "minimum": -50,
                    "maximum": 50,
                    "default": 5
                },
                "shadow_offset_y": {
                    "type": "integer",
                    "description": "阴影Y轴偏移(像素)",
                    "minimum": -50,
                    "maximum": 50,
                    "default": 5
                },
                "shadow_blur": {
                    "type": "integer",
                    "description": "阴影模糊半径",
                    "minimum": 0,
                    "maximum": 20,
                    "default": 5
                },
                "shadow_opacity": {
                    "type": "number",
                    "description": "阴影透明度(0.0-1.0)",
                    "minimum": 0.0,
                    "maximum": 1.0,
                    "default": 0.5
                },
                "output_format": {
                    "type": "string",
                    "description": "输出格式",
                    "enum": ["PNG", "JPEG", "WEBP"],
                    "default": "PNG"
                }
            },
            "required": ["image_source"]
        }
    ),

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/duke0317/ps-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server