File size: 4,913 Bytes
5e2fbf6
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
86f02e0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
import io
import gradio as gr
from PIL import Image
import vtracer
import tempfile

# Localization dictionary
TRANSLATIONS = {
    'en': {
        'title': 'Convert Image to SVG Vectors',
        'description': 'Upload an image and customize the conversion parameters as needed.'
    },
    'de': {
        'title': 'Bild in SVG-Vektoren umwandeln',
        'description': 'Laden Sie ein Bild hoch und passen Sie die Konvertierungsparameter nach Bedarf an.'
    }
}

def convert_image(image, color_mode, hierarchical, mode, filter_speckle,
 color_precision, layer_difference, corner_threshold,
 length_threshold, max_iterations, splice_threshold, path_precision):
    """Converts an image to SVG using vtracer with customizable parameters."""
    # Convert Gradio image to bytes for vtracer compatibility
    img_byte_array = io.BytesIO()
    image.save(img_byte_array, format='PNG')
    img_bytes = img_byte_array.getvalue()

    # Perform the conversion
    svg_str = vtracer.convert_raw_image_to_svg(
        img_bytes,
        img_format='png',
        colormode=color_mode.lower(),
        hierarchical=hierarchical.lower(),
        mode=mode.lower(),
        filter_speckle=int(filter_speckle),
        color_precision=int(color_precision),
        layer_difference=int(layer_difference),
        corner_threshold=int(corner_threshold),
        length_threshold=float(length_threshold),
        max_iterations=int(max_iterations),
        splice_threshold=int(splice_threshold),
        path_precision=int(path_precision)
    )

    # Save the SVG string to a temporary file
    temp_file = tempfile.NamedTemporaryFile(delete=False, suffix='.svg')
    temp_file.write(svg_str.encode('utf-8'))
    temp_file.close()

    return (
        gr.HTML(f'<svg viewBox="0 0 {image.width} {image.height}">{svg_str}</svg>'), 
        temp_file.name
    )

# Create Gradio interface
with gr.Blocks() as vector_converter_interface:
    # Language selector at the top
    language_dropdown = gr.Dropdown(
        choices=['en', 'de'], 
        value='en', 
        label='Language / Sprache'
    )
    
    # Title and description that will be updated
    title_display = gr.Markdown(f"# {TRANSLATIONS['en']['title']}")
    description_display = gr.Markdown(TRANSLATIONS['en']['description'])
    
    # Main interface components
    with gr.Row():
        with gr.Column():
            image_input = gr.Image(type="pil", label="Upload Image")
            
        with gr.Column():
            color_mode = gr.Radio(choices=["Color", "Binary"], value="Color", label="Color Mode")
            hierarchical = gr.Radio(choices=["Stacked", "Cutout"], value="Stacked", label="Hierarchical")
            mode = gr.Radio(choices=["Spline", "Polygon", "None"], value="Spline", label="Mode")
    
    with gr.Row():
        with gr.Column():
            filter_speckle = gr.Slider(minimum=1, maximum=10, value=4, step=1, label="Filter Speckle")
            color_precision = gr.Slider(minimum=1, maximum=8, value=6, step=1, label="Color Precision")
            layer_difference = gr.Slider(minimum=1, maximum=32, value=16, step=1, label="Layer Difference")
            corner_threshold = gr.Slider(minimum=10, maximum=90, value=60, step=1, label="Corner Threshold")
            
        with gr.Column():
            length_threshold = gr.Slider(minimum=3.5, maximum=10, value=4.0, step=0.5, label="Length Threshold")
            max_iterations = gr.Slider(minimum=1, maximum=20, value=10, step=1, label="Max Iterations")
            splice_threshold = gr.Slider(minimum=10, maximum=90, value=45, step=1, label="Splice Threshold")
            path_precision = gr.Slider(minimum=1, maximum=10, value=8, step=1, label="Path Precision")
    
    # Convert button
    convert_btn = gr.Button("Convert to SVG", variant="primary")
    
    # Output components
    with gr.Row():
        svg_output = gr.HTML(label="SVG Output")
        file_output = gr.File(label="Download SVG")
    
    # Function to update language
    def update_language(language):
        new_title = f"# {TRANSLATIONS[language]['title']}"
        new_description = TRANSLATIONS[language]['description']
        return new_title, new_description
    
    # Connect the language dropdown to update title and description
    language_dropdown.change(
        fn=update_language,
        inputs=[language_dropdown],
        outputs=[title_display, description_display]
    )
    
    # Connect the convert button to the conversion function
    convert_btn.click(
        fn=convert_image,
        inputs=[
            image_input, color_mode, hierarchical, mode, filter_speckle,
            color_precision, layer_difference, corner_threshold,
            length_threshold, max_iterations, splice_threshold, path_precision
        ],
        outputs=[svg_output, file_output]
    )

if __name__ == "__main__":
    vector_converter_interface.launch(enable_api=False)