cutechicken commited on
Commit
473a864
ยท
verified ยท
1 Parent(s): 09f3b95

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +95 -75
app.py CHANGED
@@ -1,9 +1,29 @@
1
  import gradio as gr
2
  import vtracer
3
  import os
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4
 
5
  def convert_to_vector(
6
  image,
 
 
7
  colormode="color",
8
  hierarchical="stacked",
9
  mode="spline",
@@ -16,16 +36,21 @@ def convert_to_vector(
16
  splice_threshold=45,
17
  path_precision=3
18
  ):
 
 
 
19
  input_path = "temp_input.jpg"
20
- output_path = "svg_output.svg"
 
 
21
 
22
- # Save the input image to a temporary file
23
  image.save(input_path)
24
 
25
- # Convert the image to SVG using VTracer
26
  vtracer.convert_image_to_svg_py(
27
  input_path,
28
- output_path,
29
  colormode=colormode,
30
  hierarchical=hierarchical,
31
  mode=mode,
@@ -38,24 +63,23 @@ def convert_to_vector(
38
  splice_threshold=int(splice_threshold),
39
  path_precision=int(path_precision)
40
  )
41
- # Read the SVG output
42
- with open(output_path, "r") as f:
43
- svg_content = f.read()
44
-
45
- # Return the SVG file path instead of content
46
- return gr.HTML(f'<svg viewBox="0 0 {image.width} {image.height}">{svg_content}</svg>'), output_path
47
- # return output_path,output_path
48
 
49
- def handle_color_mode(value):
50
- # You can change this to display the selected value without any prefix
51
- return value
 
 
 
 
 
 
 
 
52
 
 
 
53
 
54
- examples = [
55
- "examples/11.jpg",
56
- "examples/02.jpg",
57
- "examples/03.jpg",
58
- ]
59
 
60
  css = """
61
  #col-container {
@@ -73,18 +97,21 @@ css = """
73
  }
74
  """
75
 
76
- # Define the Gradio interface
77
  with gr.Blocks(css=css) as app:
78
  with gr.Column(elem_id="col-container"):
79
  gr.HTML("""
80
  <div style="text-align: center;">
81
  <h2>Image to Vector Converter โšก</h2>
82
- <p>Converts raster images (JPG, PNG, WEBP) to vector graphics (SVG).</p>
83
  </div>
84
  """)
85
  with gr.Row():
86
  with gr.Column():
87
  image_input = gr.Image(type="pil", label="Upload Image")
 
 
 
88
  with gr.Accordion("Advanced Settings", open=False):
89
  with gr.Accordion("Clustering", open=False):
90
  colormode = gr.Radio([("COLOR","color"),("B/W", "binary")], value="color", label="Color Mode", show_label=False)
@@ -95,72 +122,65 @@ with gr.Blocks(css=css) as app:
95
  with gr.Accordion("Curve Fitting", open=False):
96
  mode = gr.Radio([("SPLINE","spline"),("POLYGON", "polygon"), ("PIXEL","none")], value="spline", label="Mode", show_label=False)
97
  corner_threshold = gr.Slider(0, 180, value=60, step=1, label="Corner Threshold", info="Smoother")
98
- length_threshold = gr.Slider(3.5, 10, value=4.0, step=0.1, label="Segment Length", info ="More coarse")
99
  splice_threshold = gr.Slider(0, 180, value=45, step=1, label="Splice Threshold", info="Less accurate")
100
  max_iterations = gr.Slider(1, 20, value=10, step=1, label="Max Iterations", visible=False)
101
  path_precision = gr.Slider(1, 10, value=3, step=1, label="Path Precision", visible=False)
102
  output_text = gr.Textbox(label="Selected Mode", visible=False)
103
  with gr.Row():
104
  clear_button = gr.Button("Clear")
105
- convert_button = gr.Button("โœจ Convert to SVG", variant='primary', elem_classes=["generate-btn"])
106
 
107
  with gr.Column():
108
- html = gr.HTML(label="SVG Output") # container=True, show_label=True
109
- svg_output = gr.File(label="Download SVG")
 
 
 
 
 
 
 
110
 
111
  gr.Examples(
112
- examples = examples,
113
- fn = convert_to_vector,
114
- inputs = [image_input],
115
- outputs = [html,svg_output],
 
 
 
 
116
  cache_examples=False,
117
- run_on_click = True
118
  )
119
- # Store default values for restoration
120
- colormode.change(handle_color_mode, inputs=colormode,outputs=output_text)
121
- hierarchical.change(handle_color_mode, inputs=hierarchical,outputs=output_text)
122
- mode.change(handle_color_mode, inputs=mode,outputs=output_text)
123
- default_values = {
124
- "color_precision": 6,
125
- "layer_difference": 16
126
- }
127
 
 
128
  def clear_inputs():
129
- return gr.Image(value=None), gr.Radio(value="color"), gr.Radio(value="stacked"), gr.Radio(value="spline"), gr.Slider(value=4), gr.Slider(value=6), gr.Slider(value=16), gr.Slider(value=60), gr.Slider(value=4.0), gr.Slider(value=10), gr.Slider(value=45), gr.Slider(value=3)
130
 
 
 
131
 
132
- def update_interactivity_and_visibility(colormode, color_precision_value, layer_difference_value):
133
- is_color_mode = colormode == "color"
134
- return (
135
- gr.update(interactive=is_color_mode),
136
- gr.update(interactive=is_color_mode),
137
- gr.update(visible=is_color_mode) # Show/Hide Hierarchical Mode
138
- )
139
-
140
- colormode.change(
141
- update_interactivity_and_visibility,
142
- inputs=[colormode, color_precision, layer_difference],
143
- outputs=[color_precision, layer_difference, hierarchical]
144
  )
145
-
146
- def update_interactivity_and_visibility_for_mode(mode):
147
- is_spline_mode = mode == "spline"
148
- return (
149
- gr.update(interactive=is_spline_mode),
150
- gr.update(interactive=is_spline_mode),
151
- gr.update(interactive=is_spline_mode)
152
- )
153
-
154
- mode.change(
155
- update_interactivity_and_visibility_for_mode,
156
- inputs=[mode],
157
- outputs=[corner_threshold,length_threshold,splice_threshold]
158
  )
159
 
160
- clear_button.click(
161
- clear_inputs,
162
- outputs=[
 
163
  image_input,
 
 
164
  colormode,
165
  hierarchical,
166
  mode,
@@ -172,12 +192,14 @@ with gr.Blocks(css=css) as app:
172
  max_iterations,
173
  splice_threshold,
174
  path_precision
175
- ]
 
176
  )
177
 
178
- convert_button.click(
179
- convert_to_vector,
180
- inputs=[
 
181
  image_input,
182
  colormode,
183
  hierarchical,
@@ -190,9 +212,7 @@ with gr.Blocks(css=css) as app:
190
  max_iterations,
191
  splice_threshold,
192
  path_precision
193
- ],
194
- outputs=[html,svg_output]
195
  )
196
 
197
- # Launch the app
198
- app.launch(debug=True)
 
1
  import gradio as gr
2
  import vtracer
3
  import os
4
+ from svglib.svglib import svg2rlg
5
+ from reportlab.graphics import renderPDF
6
+ import subprocess
7
+
8
+ def convert_svg_to_ai(svg_path):
9
+ # SVG๋ฅผ PDF๋กœ ๋จผ์ € ๋ณ€ํ™˜
10
+ drawing = svg2rlg(svg_path)
11
+ pdf_path = svg_path.replace('.svg', '.pdf')
12
+ renderPDF.drawToFile(drawing, pdf_path)
13
+
14
+ # PDF๋ฅผ AI๋กœ ๋ณ€ํ™˜
15
+ ai_path = svg_path.replace('.svg', '.ai')
16
+ subprocess.run(['gs', '-dNOPAUSE', '-dBATCH', '-sDEVICE=pdfwrite',
17
+ '-sOutputFile=' + ai_path, pdf_path])
18
+
19
+ # ์ž„์‹œ PDF ํŒŒ์ผ ์‚ญ์ œ
20
+ os.remove(pdf_path)
21
+ return ai_path
22
 
23
  def convert_to_vector(
24
  image,
25
+ save_svg,
26
+ save_ai,
27
  colormode="color",
28
  hierarchical="stacked",
29
  mode="spline",
 
36
  splice_threshold=45,
37
  path_precision=3
38
  ):
39
+ if not (save_svg or save_ai):
40
+ return None, None, None # ๋‘˜ ๋‹ค ์„ ํƒ๋˜์ง€ ์•Š์€ ๊ฒฝ์šฐ
41
+
42
  input_path = "temp_input.jpg"
43
+ svg_path = "svg_output.svg"
44
+ outputs = []
45
+ preview = None
46
 
47
+ # ์ž…๋ ฅ ์ด๋ฏธ์ง€๋ฅผ ์ž„์‹œ ํŒŒ์ผ๋กœ ์ €์žฅ
48
  image.save(input_path)
49
 
50
+ # VTracer๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ด๋ฏธ์ง€๋ฅผ SVG๋กœ ๋ณ€ํ™˜
51
  vtracer.convert_image_to_svg_py(
52
  input_path,
53
+ svg_path,
54
  colormode=colormode,
55
  hierarchical=hierarchical,
56
  mode=mode,
 
63
  splice_threshold=int(splice_threshold),
64
  path_precision=int(path_precision)
65
  )
 
 
 
 
 
 
 
66
 
67
+ # SVG ํŒŒ์ผ ์ฒ˜๋ฆฌ
68
+ if save_svg:
69
+ with open(svg_path, "r") as f:
70
+ svg_content = f.read()
71
+ preview = gr.HTML(f'<svg viewBox="0 0 {image.width} {image.height}">{svg_content}</svg>')
72
+ outputs.append(svg_path)
73
+
74
+ # AI ํŒŒ์ผ ์ฒ˜๋ฆฌ
75
+ if save_ai:
76
+ ai_path = convert_svg_to_ai(svg_path)
77
+ outputs.append(ai_path)
78
 
79
+ if not save_svg: # SVG๊ฐ€ ์„ ํƒ๋˜์ง€ ์•Š์•˜๋‹ค๋ฉด ์ž„์‹œ ํŒŒ์ผ ์‚ญ์ œ
80
+ os.remove(svg_path)
81
 
82
+ return preview, outputs[0] if outputs else None, outputs[1] if len(outputs) > 1 else None
 
 
 
 
83
 
84
  css = """
85
  #col-container {
 
97
  }
98
  """
99
 
100
+ # Gradio ์ธํ„ฐํŽ˜์ด์Šค ์ •์˜
101
  with gr.Blocks(css=css) as app:
102
  with gr.Column(elem_id="col-container"):
103
  gr.HTML("""
104
  <div style="text-align: center;">
105
  <h2>Image to Vector Converter โšก</h2>
106
+ <p>Converts raster images (JPG, PNG, WEBP) to vector graphics (SVG, AI).</p>
107
  </div>
108
  """)
109
  with gr.Row():
110
  with gr.Column():
111
  image_input = gr.Image(type="pil", label="Upload Image")
112
+ with gr.Row():
113
+ save_svg = gr.Checkbox(value=True, label="Save as SVG")
114
+ save_ai = gr.Checkbox(value=False, label="Save as AI")
115
  with gr.Accordion("Advanced Settings", open=False):
116
  with gr.Accordion("Clustering", open=False):
117
  colormode = gr.Radio([("COLOR","color"),("B/W", "binary")], value="color", label="Color Mode", show_label=False)
 
122
  with gr.Accordion("Curve Fitting", open=False):
123
  mode = gr.Radio([("SPLINE","spline"),("POLYGON", "polygon"), ("PIXEL","none")], value="spline", label="Mode", show_label=False)
124
  corner_threshold = gr.Slider(0, 180, value=60, step=1, label="Corner Threshold", info="Smoother")
125
+ length_threshold = gr.Slider(3.5, 10, value=4.0, step=0.1, label="Segment Length", info="More coarse")
126
  splice_threshold = gr.Slider(0, 180, value=45, step=1, label="Splice Threshold", info="Less accurate")
127
  max_iterations = gr.Slider(1, 20, value=10, step=1, label="Max Iterations", visible=False)
128
  path_precision = gr.Slider(1, 10, value=3, step=1, label="Path Precision", visible=False)
129
  output_text = gr.Textbox(label="Selected Mode", visible=False)
130
  with gr.Row():
131
  clear_button = gr.Button("Clear")
132
+ convert_button = gr.Button("โœจ Convert", variant='primary', elem_classes=["generate-btn"])
133
 
134
  with gr.Column():
135
+ preview = gr.HTML(label="Preview")
136
+ svg_output = gr.File(label="SVG Output", visible=True)
137
+ ai_output = gr.File(label="AI Output", visible=True)
138
+
139
+ examples = [
140
+ "examples/11.jpg",
141
+ "examples/02.jpg",
142
+ "examples/03.jpg",
143
+ ]
144
 
145
  gr.Examples(
146
+ examples=examples,
147
+ fn=convert_to_vector,
148
+ inputs=[
149
+ image_input,
150
+ save_svg,
151
+ save_ai
152
+ ],
153
+ outputs=[preview, svg_output, ai_output],
154
  cache_examples=False,
155
+ run_on_click=True
156
  )
 
 
 
 
 
 
 
 
157
 
158
+ # ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ
159
  def clear_inputs():
160
+ return [None] * 12
161
 
162
+ def update_output_visibility(save_svg, save_ai):
163
+ return gr.update(visible=save_svg), gr.update(visible=save_ai)
164
 
165
+ # ์ฒดํฌ๋ฐ•์Šค ์ƒํƒœ์— ๋”ฐ๋ฅธ ์ถœ๋ ฅ ํŒŒ์ผ ์ปดํฌ๋„ŒํŠธ ํ‘œ์‹œ/์ˆจ๊น€
166
+ save_svg.change(
167
+ update_output_visibility,
168
+ inputs=[save_svg, save_ai],
169
+ outputs=[svg_output, ai_output]
 
 
 
 
 
 
 
170
  )
171
+ save_ai.change(
172
+ update_output_visibility,
173
+ inputs=[save_svg, save_ai],
174
+ outputs=[svg_output, ai_output]
 
 
 
 
 
 
 
 
 
175
  )
176
 
177
+ # ๋ณ€ํ™˜ ๋ฒ„ํŠผ ํด๋ฆญ ์ด๋ฒคํŠธ
178
+ convert_button.click(
179
+ convert_to_vector,
180
+ inputs=[
181
  image_input,
182
+ save_svg,
183
+ save_ai,
184
  colormode,
185
  hierarchical,
186
  mode,
 
192
  max_iterations,
193
  splice_threshold,
194
  path_precision
195
+ ],
196
+ outputs=[preview, svg_output, ai_output]
197
  )
198
 
199
+ # Clear ๋ฒ„ํŠผ ์ด๋ฒคํŠธ
200
+ clear_button.click(
201
+ clear_inputs,
202
+ outputs=[
203
  image_input,
204
  colormode,
205
  hierarchical,
 
212
  max_iterations,
213
  splice_threshold,
214
  path_precision
215
+ ]
 
216
  )
217
 
218
+ app.launch(debug=True)