| """ |
| Any2SVG - Image to SVG Vectorization Tool |
| |
| A Gradio 6 application that converts raster images to SVG vector graphics. |
| Supports MCP server integration for AI agent tool calling. |
| |
| Purpose: Convert any raster image (PNG, JPG, WebP, etc.) to SVG format |
| Inputs: Image file, vectorization parameters |
| Outputs: SVG file path or SVG content |
| Examples: Logo vectorization, artwork conversion, icon generation |
| Edge cases: Very large images, transparent backgrounds, gradients |
| Errors: Invalid image format, file I/O errors |
| """ |
|
|
| import os |
| import sys |
| from pathlib import Path |
|
|
| import gradio as gr |
| from PIL import Image |
|
|
| |
| sys.path.insert(0, str(Path(__file__).parent)) |
|
|
| from dna.atoms.vectorizer import ( |
| VectorizerConfig, |
| image_to_svg_file, |
| image_to_svg_string, |
| validate_image, |
| VectorizationError, |
| InvalidImageError, |
| ) |
| from dna.molecules.mcp_handler import get_output_directory, process_mcp_request |
|
|
|
|
| def convert_image_to_svg( |
| image: Image.Image, |
| color_mode: str = "color", |
| filter_speckle: int = 4, |
| color_precision: int = 6, |
| corner_threshold: int = 60, |
| path_precision: int = 3, |
| ) -> tuple[str, str]: |
| """ |
| Convert a raster image to SVG vector graphics. |
| |
| Args: |
| image: The input image to convert (PIL Image). |
| color_mode: Vectorization mode - 'color' for full color, 'binary' for black/white. |
| filter_speckle: Remove small artifacts (pixels). Higher = more filtering. |
| color_precision: Color quantization bits (1-8). Lower = fewer colors. |
| corner_threshold: Angle threshold for corner detection (degrees). |
| path_precision: Decimal precision for path coordinates. |
| |
| Returns: |
| Tuple of (svg_file_path, svg_content) - path to saved SVG and its content. |
| |
| Raises: |
| ValueError: If image is None or invalid. |
| IOError: If file operations fail. |
| """ |
| config = VectorizerConfig( |
| color_mode=color_mode, |
| filter_speckle=filter_speckle, |
| color_precision=color_precision, |
| corner_threshold=corner_threshold, |
| path_precision=path_precision, |
| ) |
| |
| output_dir = get_output_directory() |
| svg_path = image_to_svg_file(image, output_dir, config=config) |
| |
| with open(svg_path, "r", encoding="utf-8") as f: |
| svg_content = f.read() |
| |
| return str(svg_path), svg_content |
|
|
|
|
| def process_image( |
| image: Image.Image, |
| color_mode: str, |
| filter_speckle: int, |
| color_precision: int, |
| corner_threshold: int, |
| path_precision: int, |
| ) -> tuple[str, str, str]: |
| """ |
| Process an image and convert it to SVG format. |
| |
| Args: |
| image: The input raster image to vectorize. |
| color_mode: 'color' for full color output, 'binary' for black and white. |
| filter_speckle: Speckle filter size to remove small artifacts (1-100). |
| color_precision: Color precision bits for quantization (1-8). |
| corner_threshold: Corner detection angle threshold in degrees (0-180). |
| path_precision: Decimal precision for SVG path coordinates (1-8). |
| |
| Returns: |
| Tuple of (status_message, svg_file_path, svg_preview_content). |
| """ |
| try: |
| svg_path, svg_content = convert_image_to_svg( |
| image=image, |
| color_mode=color_mode, |
| filter_speckle=filter_speckle, |
| color_precision=color_precision, |
| corner_threshold=corner_threshold, |
| path_precision=path_precision, |
| ) |
| |
| status = f"✅ SVG saved to: {svg_path}" |
| return status, svg_path, svg_content |
| |
| except Exception as e: |
| error_msg = f"❌ Error: {str(e)}" |
| return error_msg, "", "" |
|
|
|
|
| |
| with gr.Blocks( |
| title="Any2SVG - Image to SVG Converter", |
| theme=gr.themes.Soft(), |
| ) as demo: |
| gr.Markdown( |
| """ |
| # 🎨 Any2SVG - Image to SVG Converter |
| |
| Convert raster images (PNG, JPG, WebP, etc.) to scalable vector graphics (SVG). |
| |
| **Features:** |
| - High-quality vectorization using vtracer |
| - Configurable color modes and precision |
| - MCP server support for AI agent integration |
| """ |
| ) |
|
|
| with gr.Row(): |
| with gr.Column(scale=1): |
| input_image = gr.Image( |
| label="Input Image", |
| type="pil", |
| sources=["upload", "clipboard"], |
| ) |
| |
| with gr.Accordion("Vectorization Settings", open=False): |
| color_mode = gr.Radio( |
| choices=["color", "binary"], |
| value="color", |
| label="Color Mode", |
| info="'color' for full color, 'binary' for black/white", |
| ) |
| filter_speckle = gr.Slider( |
| minimum=1, |
| maximum=100, |
| value=4, |
| step=1, |
| label="Filter Speckle", |
| info="Remove small artifacts (higher = more filtering)", |
| ) |
| color_precision = gr.Slider( |
| minimum=1, |
| maximum=8, |
| value=6, |
| step=1, |
| label="Color Precision", |
| info="Color quantization bits (lower = fewer colors)", |
| ) |
| corner_threshold = gr.Slider( |
| minimum=0, |
| maximum=180, |
| value=60, |
| step=1, |
| label="Corner Threshold", |
| info="Angle threshold for corner detection (degrees)", |
| ) |
| path_precision = gr.Slider( |
| minimum=1, |
| maximum=8, |
| value=3, |
| step=1, |
| label="Path Precision", |
| info="Decimal precision for path coordinates", |
| ) |
|
|
| convert_btn = gr.Button("🔄 Convert to SVG", variant="primary", size="lg") |
|
|
| with gr.Column(scale=1): |
| status_output = gr.Textbox( |
| label="Status", |
| interactive=False, |
| ) |
| svg_file_output = gr.File( |
| label="Download SVG", |
| ) |
| svg_preview = gr.Code( |
| label="SVG Preview", |
| language="html", |
| lines=15, |
| ) |
|
|
| |
| convert_btn.click( |
| fn=process_image, |
| inputs=[ |
| input_image, |
| color_mode, |
| filter_speckle, |
| color_precision, |
| corner_threshold, |
| path_precision, |
| ], |
| outputs=[status_output, svg_file_output, svg_preview], |
| ) |
|
|
| |
| gr.Examples( |
| examples=[ |
| ["https://upload.wikimedia.org/wikipedia/commons/thumb/4/47/PNG_transparency_demonstration_1.png/280px-PNG_transparency_demonstration_1.png"], |
| ], |
| inputs=[input_image], |
| label="Example Images", |
| ) |
|
|
|
|
| |
| @gr.api( |
| inputs=[ |
| gr.Image(type="pil"), |
| gr.Textbox(value="color"), |
| gr.Number(value=4), |
| gr.Number(value=6), |
| ], |
| outputs=[gr.Textbox(), gr.Textbox()], |
| ) |
| def image_to_svg( |
| image: Image.Image, |
| color_mode: str = "color", |
| filter_speckle: int = 4, |
| color_precision: int = 6, |
| ) -> tuple[str, str]: |
| """ |
| Convert any raster image to SVG vector graphics. |
| |
| This tool accepts an image and returns the path to the generated SVG file |
| along with the SVG content. The SVG is saved to the configured output directory. |
| |
| Args: |
| image: The input raster image (PNG, JPG, WebP, etc.) to vectorize. |
| color_mode: Vectorization mode - 'color' for full color, 'binary' for B&W. |
| filter_speckle: Speckle filter size (1-100). Higher removes more artifacts. |
| color_precision: Color precision bits (1-8). Lower means fewer colors. |
| |
| Returns: |
| Tuple of (svg_file_path, svg_content). |
| """ |
| svg_path, svg_content = convert_image_to_svg( |
| image=image, |
| color_mode=color_mode, |
| filter_speckle=int(filter_speckle), |
| color_precision=int(color_precision), |
| ) |
| return svg_path, svg_content |
|
|
|
|
| if __name__ == "__main__": |
| |
| get_output_directory() |
| |
| |
| demo.launch( |
| mcp_server=True, |
| server_name="0.0.0.0", |
| server_port=7860, |
| share=False, |
| ) |
|
|