aaurelions commited on
Commit
44bf299
·
verified ·
1 Parent(s): fe88f1f

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +40 -33
app.py CHANGED
@@ -6,16 +6,15 @@ import tempfile
6
  def image_to_svg(image, colormode, hierarchical, filter_speckle, color_precision, layer_difference, mode, corner_threshold, length_threshold, splice_threshold, path_precision):
7
  """
8
  Converts an input image to an SVG string using vtracer.
9
- This function is triggered by clicking the 'Convert' button.
10
  """
11
  if image is None:
12
- return None, "Upload an image and click 'Convert'.", None
 
13
 
14
  input_path = image
15
 
16
- # **FIX:** Create a named temporary file that will NOT be deleted automatically.
17
- # We use delete=False to ensure the file persists after the function returns.
18
- # Gradio will handle the cleanup of this file from its own cache.
19
  with tempfile.NamedTemporaryFile(delete=False, suffix=".svg", mode='w', encoding='utf-8') as temp_output_file:
20
  output_path = temp_output_file.name
21
 
@@ -41,8 +40,7 @@ def image_to_svg(image, colormode, hierarchical, filter_speckle, color_precision
41
  with open(output_path, "r", encoding='utf-8') as f:
42
  svg_content = f.read()
43
 
44
- # Return the path for file download, the SVG code, and the path for the image preview.
45
- # The file at output_path now exists and Gradio can access it.
46
  return output_path, svg_content, output_path
47
 
48
  except Exception as e:
@@ -53,16 +51,31 @@ def image_to_svg(image, colormode, hierarchical, filter_speckle, color_precision
53
 
54
  # --- Gradio User Interface ---
55
  with gr.Blocks(theme=gr.themes.Soft(primary_hue="blue")) as demo:
56
- gr.Markdown("# IMG2SVG: Image to SVG Converter")
57
- gr.Markdown("Upload an image, adjust the settings, and click **Convert**.")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
58
 
 
59
  with gr.Row(variant="panel"):
60
- # ----- Input Column -----
61
  with gr.Column(scale=1):
62
- image_input = gr.Image(type="filepath", label="Upload Image", sources=["upload", "clipboard"])
63
-
64
  with gr.Group():
65
- gr.Markdown("### Clustering")
66
  colormode = gr.Radio(["Color", "B/W"], value="Color", label="Color Mode")
67
  hierarchical = gr.Radio(["Stacked", "Cutout"], value="Stacked", label="Hierarchical Mode")
68
  filter_speckle = gr.Slider(0, 128, value=4, step=1, label="Filter Speckle (Cleaner)")
@@ -70,46 +83,40 @@ with gr.Blocks(theme=gr.themes.Soft(primary_hue="blue")) as demo:
70
  layer_difference = gr.Slider(0, 128, value=16, step=1, label="Gradient Step (Less layers)")
71
 
72
  with gr.Group():
73
- gr.Markdown("### Curve Fitting")
74
  mode = gr.Radio(["Spline", "Polygon", "Pixel"], value="Spline", label="Mode")
75
  corner_threshold = gr.Slider(0, 180, value=60, step=1, label="Corner Threshold (Smoother)")
76
  length_threshold = gr.Slider(0, 10, value=4.0, step=0.5, label="Segment Length (More coarse)")
77
  splice_threshold = gr.Slider(0, 180, value=45, step=1, label="Splice Threshold (Less accurate)")
78
  path_precision = gr.Slider(1, 8, value=3, step=1, label="Path Precision")
79
-
80
- convert_button = gr.Button("Convert", variant="primary")
81
 
82
  # ----- Output Column -----
83
  with gr.Column(scale=2):
 
84
  with gr.Tabs():
85
  with gr.TabItem("SVG Preview"):
86
- svg_image_output = gr.Image(label="SVG Preview", interactive=False)
87
  with gr.TabItem("SVG Code"):
88
- svg_text_output = gr.Code(label="SVG Code", language="html", interactive=False)
89
 
90
  svg_file_output = gr.File(label="Download SVG")
91
 
92
- with gr.Accordion("How VTracer Works (Technical Details)", open=False):
93
- gr.Markdown(
94
- """
95
- This tool uses VTracer to convert raster images into vector graphics. The process involves several key stages:
96
-
97
- 1. **Clustering**: The image is grouped into clusters of similar colors.
98
- 2. **Path Walking**: An algorithm traces the outline of each cluster to create a raw path.
99
- 3. **Path Simplification**: The path is simplified to remove pixelation and reduce points.
100
- 4. **Path Smoothing**: A corner-preserving algorithm refines the path to allow for smooth curves.
101
- 5. **Curve Fitting**: The path is segmented and approximated with Bézier curves to create the final SVG.
102
- """
103
- )
104
-
105
- inputs = [
106
  image_input, colormode, hierarchical, filter_speckle, color_precision,
107
  layer_difference, mode, corner_threshold, length_threshold, splice_threshold, path_precision
108
  ]
109
 
 
110
  outputs = [svg_file_output, svg_text_output, svg_image_output]
111
 
112
- convert_button.click(fn=image_to_svg, inputs=inputs, outputs=outputs)
 
 
 
 
113
 
114
  # To launch the application
115
  demo.launch()
 
6
  def image_to_svg(image, colormode, hierarchical, filter_speckle, color_precision, layer_difference, mode, corner_threshold, length_threshold, splice_threshold, path_precision):
7
  """
8
  Converts an input image to an SVG string using vtracer.
9
+ This function is triggered automatically when any of the input controls change.
10
  """
11
  if image is None:
12
+ # A clear startup state before an image is uploaded.
13
+ return None, "Upload an image to see the SVG preview and code.", None
14
 
15
  input_path = image
16
 
17
+ # Create a persistent temporary file that Gradio can access after the function returns.
 
 
18
  with tempfile.NamedTemporaryFile(delete=False, suffix=".svg", mode='w', encoding='utf-8') as temp_output_file:
19
  output_path = temp_output_file.name
20
 
 
40
  with open(output_path, "r", encoding='utf-8') as f:
41
  svg_content = f.read()
42
 
43
+ # Return the path for the file download, the SVG code, and the path for the image preview.
 
44
  return output_path, svg_content, output_path
45
 
46
  except Exception as e:
 
51
 
52
  # --- Gradio User Interface ---
53
  with gr.Blocks(theme=gr.themes.Soft(primary_hue="blue")) as demo:
54
+
55
+ # --- Top Row: Upload and Project Info ---
56
+ with gr.Row():
57
+ with gr.Column(scale=1):
58
+ image_input = gr.Image(type="filepath", label="Upload Your Image", sources=["upload", "clipboard"])
59
+ with gr.Column(scale=2):
60
+ gr.Markdown(
61
+ """
62
+ # IMG2SVG: Real-time SVG Converter
63
+ This application converts raster images (like JPG, PNG) into clean, scalable vector graphics (SVG) using the powerful `vtracer` library.
64
+
65
+ **How to use:**
66
+ 1. Upload an image.
67
+ 2. Adjust the settings in the control panel below.
68
+ 3. The SVG preview will update automatically.
69
+ """
70
+ )
71
 
72
+ # --- Bottom Row: Controls and Output ---
73
  with gr.Row(variant="panel"):
74
+ # ----- Control Panel Column -----
75
  with gr.Column(scale=1):
76
+ gr.Markdown("### Control Panel")
 
77
  with gr.Group():
78
+ gr.Markdown("#### Clustering")
79
  colormode = gr.Radio(["Color", "B/W"], value="Color", label="Color Mode")
80
  hierarchical = gr.Radio(["Stacked", "Cutout"], value="Stacked", label="Hierarchical Mode")
81
  filter_speckle = gr.Slider(0, 128, value=4, step=1, label="Filter Speckle (Cleaner)")
 
83
  layer_difference = gr.Slider(0, 128, value=16, step=1, label="Gradient Step (Less layers)")
84
 
85
  with gr.Group():
86
+ gr.Markdown("#### Curve Fitting")
87
  mode = gr.Radio(["Spline", "Polygon", "Pixel"], value="Spline", label="Mode")
88
  corner_threshold = gr.Slider(0, 180, value=60, step=1, label="Corner Threshold (Smoother)")
89
  length_threshold = gr.Slider(0, 10, value=4.0, step=0.5, label="Segment Length (More coarse)")
90
  splice_threshold = gr.Slider(0, 180, value=45, step=1, label="Splice Threshold (Less accurate)")
91
  path_precision = gr.Slider(1, 8, value=3, step=1, label="Path Precision")
 
 
92
 
93
  # ----- Output Column -----
94
  with gr.Column(scale=2):
95
+ gr.Markdown("### Result")
96
  with gr.Tabs():
97
  with gr.TabItem("SVG Preview"):
98
+ svg_image_output = gr.Image(label="Live SVG Preview", interactive=False)
99
  with gr.TabItem("SVG Code"):
100
+ svg_text_output = gr.Code(label="Generated SVG Code", language="html", interactive=False)
101
 
102
  svg_file_output = gr.File(label="Download SVG")
103
 
104
+ # --- Event Handling for Live Update ---
105
+
106
+ # A list of all the input controls that should trigger a re-render.
107
+ controls = [
 
 
 
 
 
 
 
 
 
 
108
  image_input, colormode, hierarchical, filter_speckle, color_precision,
109
  layer_difference, mode, corner_threshold, length_threshold, splice_threshold, path_precision
110
  ]
111
 
112
+ # A list of all the components that will display the output.
113
  outputs = [svg_file_output, svg_text_output, svg_image_output]
114
 
115
+ # This loop attaches an event listener to every control.
116
+ # The 'debounce' parameter is crucial for performance. It waits for 0.5s of inactivity
117
+ # before triggering the conversion, ensuring it doesn't run excessively while a slider is being dragged.
118
+ for component in controls:
119
+ component.change(fn=image_to_svg, inputs=controls, outputs=outputs, debounce=0.5)
120
 
121
  # To launch the application
122
  demo.launch()