File size: 6,576 Bytes
67f1b4c
 
 
3fa54b5
 
 
d541579
3fa54b5
 
 
 
 
 
 
91595f2
 
 
 
 
 
 
3fa54b5
 
91595f2
3fa54b5
 
 
 
 
91595f2
3fa54b5
 
 
 
 
 
 
 
 
 
 
 
 
 
91595f2
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3fa54b5
91595f2
3fa54b5
3074852
 
 
 
91595f2
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
bbf7bd0
91595f2
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3074852
91595f2
 
 
 
 
 
 
 
 
 
 
 
 
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
125
126
127
128
129
130
131
132
133
134
135
136
137
import os
os.system("pip uninstall -y gradio")
os.system("pip install gradio>=4.44.1")
import io
import gradio as gr
from PIL import Image
import vtracer
import tempfile

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."""

    if image is None:
        # Handle case where no image is uploaded yet, or it's cleared.
        # You might want to return empty/default outputs or raise a Gradio error.
        # For simplicity, returning None which might clear the outputs or show placeholders.
        # Depending on Gradio version, this might need more graceful handling.
        return None, None

    # Convert Gradio image to bytes for vtracer compatibility
    img_byte_array = io.BytesIO()
    image.save(img_byte_array, format='PNG') # Ensure input image is PIL, format can be inferred by PIL
    img_bytes = img_byte_array.getvalue()

    # Perform the conversion
    svg_str = vtracer.convert_raw_image_to_svg(
        img_bytes,
        # img_format='png', # vtracer can often infer this, but specifying is safer
        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
    # It's crucial that this temp file is not deleted immediately
    # so Gradio's File component can serve it.
    # NamedTemporaryFile needs to be kept open or its name stored carefully.
    # A simpler approach for HF Spaces might be to write to a known path if persistence across calls isn't an issue,
    # but NamedTemporaryFile with delete=False is generally fine.
    temp_file = tempfile.NamedTemporaryFile(delete=False, suffix='.svg', mode='w', encoding='utf-8')
    temp_file.write(svg_str)
    temp_file.close() # Close the file handle, but the file itself remains due to delete=False

    # For gr.HTML, it's often better to pass the full SVG string.
    # vtracer usually produces a full SVG document including <svg> tags.
    # If image is None initially, image.width and image.height would cause an error.
    # The viewBox construction you had is fine if svg_str is just the inner content.
    # If svg_str is a full SVG, just use gr.HTML(svg_str).
    # Assuming svg_str is a full SVG document:
    html_output = gr.HTML(svg_str)
    # If you want to ensure a specific viewBox based on original image for the HTML display:
    # html_output = gr.HTML(f'<div style="width:{image.width}px; height:{image.height}px; overflow:auto;"><svg viewBox="0 0 {image.width} {image.height}">{svg_str}</svg></div>')
    # However, simply `gr.HTML(svg_str)` is usually sufficient if vtracer provides proper width/height in the SVG.

    return html_output, temp_file.name

# Gradio interface
iface = gr.Blocks()

with iface:
    gr.Markdown("# Hepzeka.com - Resmi SVG ye Dönüştür") # Using Markdown for title
    gr.Markdown("Bir resim yükleyin ve dönüştürme parametrelerini ihtiyacınıza göre özelleştirin.") # Using Markdown for description

    with gr.Row():
        with gr.Column(scale=1):
            image_input = gr.Image(type="pil", label="Upload Image")
            color_mode_input = gr.Radio(choices=["Color", "Binary"], value="Color", label="Color Mode")
            hierarchical_input = gr.Radio(choices=["Stacked", "Cutout"], value="Stacked", label="Hierarchical")
            mode_input = gr.Radio(choices=["Spline", "Polygon", "None"], value="Spline", label="Mode")
            filter_speckle_input = gr.Slider(minimum=1, maximum=10, value=4, step=1, label="Filter Speckle")
            color_precision_input = gr.Slider(minimum=1, maximum=8, value=6, step=1, label="Color Precision")
            layer_difference_input = gr.Slider(minimum=1, maximum=32, value=16, step=1, label="Layer Difference")
            corner_threshold_input = gr.Slider(minimum=10, maximum=90, value=60, step=1, label="Corner Threshold")
            length_threshold_input = gr.Slider(minimum=3.5, maximum=10, value=4.0, step=0.5, label="Length Threshold")
            max_iterations_input = gr.Slider(minimum=1, maximum=20, value=10, step=1, label="Max Iterations")
            splice_threshold_input = gr.Slider(minimum=10, maximum=90, value=45, step=1, label="Splice Threshold")
            path_precision_input = gr.Slider(minimum=1, maximum=10, value=8, step=1, label="Path Precision")
            
            submit_button = gr.Button("Convert to SVG")

        with gr.Column(scale=1):
            svg_output_display = gr.HTML(label="SVG Output")
            svg_download_link = gr.File(label="Download SVG")

    inputs_list = [
        image_input,
        color_mode_input,
        hierarchical_input,
        mode_input,
        filter_speckle_input,
        color_precision_input,
        layer_difference_input,
        corner_threshold_input,
        length_threshold_input,
        max_iterations_input,
        splice_threshold_input,
        path_precision_input
    ]
    outputs_list = [
        svg_output_display,
        svg_download_link
    ]

    # Using gr.Interface() inside gr.Blocks is one way,
    # but for more control with Blocks, you typically define event listeners.
    # However, your original structure with gr.Interface is fine.
    # To make it more "Blocks-idiomatic" with the defined components:
    submit_button.click(
        fn=convert_image,
        inputs=inputs_list,
        outputs=outputs_list
    )
    
    # If you prefer to keep your original gr.Interface structure:
    # (Comment out the submit_button.click above and uncomment the gr.Interface below)
    # gr.Interface(
    #     fn=convert_image,
    #     inputs=inputs_list, # or define them inline as you had
    #     outputs=outputs_list, # or define them inline
    #     # title and description can be handled by gr.Markdown elements at the top if using Blocks for layout
    # )

# Launch the interface
# For Hugging Face Spaces, share=True is not needed and can sometimes cause issues.
# Spaces handles the public URL.
iface.launch()