Spaces:
Running
Running
Upload png2svg.py
Browse files- png2svg.py +172 -0
png2svg.py
ADDED
@@ -0,0 +1,172 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import vtracer
|
2 |
+
import gradio as gr
|
3 |
+
|
4 |
+
from PIL import Image
|
5 |
+
from io import BytesIO
|
6 |
+
import base64
|
7 |
+
|
8 |
+
# Convert Image to Base64
|
9 |
+
def im_2_b64(image):
|
10 |
+
buff = BytesIO()
|
11 |
+
image.save(buff, format="PNG")
|
12 |
+
img_str = base64.b64encode(buff.getvalue())
|
13 |
+
return img_str
|
14 |
+
|
15 |
+
# Save Base64 to png Image
|
16 |
+
def b64_2_img(data, out_file = './temp.png'):
|
17 |
+
buff = BytesIO(base64.b64decode(data))
|
18 |
+
img = Image.open(buff)
|
19 |
+
img.save(out_file)
|
20 |
+
return out_file
|
21 |
+
|
22 |
+
|
23 |
+
def png2svg(png_file,png_b64,svg_file,
|
24 |
+
colormode,
|
25 |
+
hierarchical,
|
26 |
+
mode,
|
27 |
+
filter_speckle,
|
28 |
+
color_precision,
|
29 |
+
layer_difference,
|
30 |
+
corner_threshold,
|
31 |
+
length_threshold,
|
32 |
+
max_iterations,
|
33 |
+
splice_threshold,
|
34 |
+
path_precision):
|
35 |
+
|
36 |
+
|
37 |
+
if len(png_b64):
|
38 |
+
png_file = b64_2_img(png_b64[2:-1])
|
39 |
+
|
40 |
+
params = {'colormode': colormode,
|
41 |
+
'hierarchical': hierarchical,
|
42 |
+
'mode':mode,
|
43 |
+
'filter_speckle':filter_speckle,
|
44 |
+
'color_precision':color_precision,
|
45 |
+
'layer_difference':layer_difference,
|
46 |
+
'corner_threshold':corner_threshold,
|
47 |
+
'length_threshold':length_threshold,
|
48 |
+
'max_iterations':max_iterations,
|
49 |
+
'splice_threshold':splice_threshold,
|
50 |
+
'path_precision':path_precision}
|
51 |
+
|
52 |
+
vtracer.convert_image_to_svg_py(png_file, svg_file, **params)
|
53 |
+
return svg_file
|
54 |
+
|
55 |
+
|
56 |
+
# Example Data
|
57 |
+
img = Image.open('./example.png')
|
58 |
+
img_b64 = im_2_b64(img)
|
59 |
+
|
60 |
+
|
61 |
+
# Interface
|
62 |
+
with gr.Blocks() as interface:
|
63 |
+
# Title
|
64 |
+
gr.Markdown("# PNG to SVG Converter")
|
65 |
+
# Heading
|
66 |
+
gr.Markdown("Converts given png to svg using vtracer.")
|
67 |
+
|
68 |
+
with gr.Accordion("File IO"):
|
69 |
+
# file io
|
70 |
+
png_file = gr.File(label = "Input file")
|
71 |
+
png_b64 = gr.Textbox(label = "Input image b64", value=img_b64)
|
72 |
+
svg_file = gr.Textbox(label = "Output file", placeholder="out.svg")
|
73 |
+
|
74 |
+
# Parameters
|
75 |
+
with gr.Accordion("Parameters"):
|
76 |
+
colormode = gr.Dropdown(
|
77 |
+
label = 'Color mode',
|
78 |
+
choices = ['color','binary'],
|
79 |
+
value = 'color',
|
80 |
+
interactive=True)
|
81 |
+
hierarchical = gr.Dropdown(
|
82 |
+
label = 'Hierarchical',
|
83 |
+
choices = ['stacked','cutout'],
|
84 |
+
value = 'stacked',
|
85 |
+
interactive=True)
|
86 |
+
mode = gr.Dropdown(
|
87 |
+
label = 'Curve fitting mode',
|
88 |
+
choices = ['spline','polygon', 'pixel'],
|
89 |
+
value = 'spline',
|
90 |
+
interactive=True)
|
91 |
+
filter_speckle = gr.Slider(
|
92 |
+
label = 'Filter specles smaller than...',
|
93 |
+
minimum = 0,
|
94 |
+
maximum = 128,
|
95 |
+
step = 1,
|
96 |
+
value = 4,
|
97 |
+
interactive=True)
|
98 |
+
color_precision = gr.Slider(
|
99 |
+
label = 'Color precision',
|
100 |
+
minimum = 1,
|
101 |
+
maximum = 8,
|
102 |
+
step = 1,
|
103 |
+
value = 6,
|
104 |
+
interactive=True)
|
105 |
+
layer_difference = gr.Slider(
|
106 |
+
label = 'Gradient step size',
|
107 |
+
minimum = 0,
|
108 |
+
maximum = 128,
|
109 |
+
step = 1,
|
110 |
+
value = 16,
|
111 |
+
interactive=True)
|
112 |
+
corner_threshold = gr.Slider(
|
113 |
+
label = 'Corner thershold',
|
114 |
+
minimum = 0,
|
115 |
+
maximum = 180,
|
116 |
+
step = 1,
|
117 |
+
value = 60,
|
118 |
+
interactive=True)
|
119 |
+
length_threshold = gr.Slider(
|
120 |
+
label = 'Segment length',
|
121 |
+
minimum = 3.5,
|
122 |
+
maximum = 10,
|
123 |
+
value = 10,
|
124 |
+
interactive=True)
|
125 |
+
max_iterations = gr.Slider(
|
126 |
+
label = 'Segment length',
|
127 |
+
minimum = 3.5,
|
128 |
+
maximum = 10,
|
129 |
+
value = 10,
|
130 |
+
interactive=True)
|
131 |
+
splice_threshold = gr.Slider(
|
132 |
+
label = 'Splice thereshold',
|
133 |
+
minimum = 0,
|
134 |
+
maximum = 180,
|
135 |
+
value = 45,
|
136 |
+
interactive=True)
|
137 |
+
path_precision = gr.Slider(
|
138 |
+
label = 'Splice thereshold',
|
139 |
+
minimum = 0,
|
140 |
+
maximum = 16,
|
141 |
+
step = 1,
|
142 |
+
value = 8,
|
143 |
+
interactive=True)
|
144 |
+
|
145 |
+
with gr.Accordion("Output SVG File"):
|
146 |
+
out_file = gr.File()
|
147 |
+
|
148 |
+
|
149 |
+
# Convert
|
150 |
+
print(colormode.value)
|
151 |
+
convert_button = gr.Button("Convert")
|
152 |
+
convert_button.click(png2svg,
|
153 |
+
[
|
154 |
+
png_file,
|
155 |
+
png_b64,
|
156 |
+
svg_file,
|
157 |
+
colormode,
|
158 |
+
hierarchical,
|
159 |
+
mode,
|
160 |
+
filter_speckle,
|
161 |
+
color_precision,
|
162 |
+
layer_difference,
|
163 |
+
corner_threshold,
|
164 |
+
length_threshold,
|
165 |
+
max_iterations,
|
166 |
+
splice_threshold,
|
167 |
+
path_precision],
|
168 |
+
out_file)
|
169 |
+
|
170 |
+
if __name__ == '__main__':
|
171 |
+
interface.launch()
|
172 |
+
|