Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
@@ -1,42 +1,85 @@
|
|
|
|
1 |
import gradio as gr
|
2 |
-
import cairosvg
|
3 |
from PIL import Image
|
4 |
-
import
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
5 |
|
6 |
-
|
7 |
-
# Convert the uploaded image to bytes
|
8 |
-
image_bytes = io.BytesIO()
|
9 |
-
image.save(image_bytes, format='PNG')
|
10 |
-
image_bytes = image_bytes.getvalue()
|
11 |
-
|
12 |
-
# Convert the PNG image to SVG using cairosvg
|
13 |
-
svg_bytes = cairosvg.svg2svg(bytestring=image_bytes, scale=scale)
|
14 |
-
|
15 |
-
# Save the SVG output to a file
|
16 |
-
output_svg = 'output_image.svg'
|
17 |
-
with open(output_svg, 'wb') as f:
|
18 |
-
f.write(svg_bytes)
|
19 |
-
|
20 |
-
return output_svg
|
21 |
-
|
22 |
-
# Set up Gradio interface with customizable options
|
23 |
-
def create_gradio_interface():
|
24 |
-
with gr.Blocks() as interface:
|
25 |
-
gr.Markdown("# Image to SVG Converter")
|
26 |
-
gr.Markdown("Upload an image and customize the options to convert it to a high-quality SVG file.")
|
27 |
-
|
28 |
-
with gr.Row():
|
29 |
-
image_input = gr.Image(type="pil", label="Upload Image")
|
30 |
-
scale_input = gr.Slider(0.5, 5.0, value=1.0, label="Scale")
|
31 |
-
|
32 |
-
output_file = gr.File(label="Download SVG")
|
33 |
-
|
34 |
-
convert_button = gr.Button("Convert Image to SVG")
|
35 |
-
convert_button.click(fn=convert_image_to_svg, inputs=[image_input, scale_input], outputs=output_file)
|
36 |
-
|
37 |
-
return interface
|
38 |
-
|
39 |
-
# Launch the Gradio interface
|
40 |
-
if __name__ == "__main__":
|
41 |
-
interface = create_gradio_interface()
|
42 |
-
interface.launch()
|
|
|
1 |
+
import io
|
2 |
import gradio as gr
|
|
|
3 |
from PIL import Image
|
4 |
+
import vtracer
|
5 |
+
import tempfile
|
6 |
+
|
7 |
+
def convert_image(image, color_mode, hierarchical, mode, filter_speckle,
|
8 |
+
color_precision, layer_difference, corner_threshold,
|
9 |
+
length_threshold, max_iterations, splice_threshold, path_precision):
|
10 |
+
"""Converts an image to SVG using vtracer with customizable parameters."""
|
11 |
+
|
12 |
+
# Convert Gradio image to bytes for vtracer compatibility
|
13 |
+
img_byte_array = io.BytesIO()
|
14 |
+
image.save(img_byte_array, format='PNG')
|
15 |
+
img_bytes = img_byte_array.getvalue()
|
16 |
+
|
17 |
+
# Perform the conversion
|
18 |
+
svg_str = vtracer.convert_raw_image_to_svg(
|
19 |
+
img_bytes,
|
20 |
+
img_format='png',
|
21 |
+
colormode=color_mode.lower(),
|
22 |
+
hierarchical=hierarchical.lower(),
|
23 |
+
mode=mode.lower(),
|
24 |
+
filter_speckle=int(filter_speckle),
|
25 |
+
color_precision=int(color_precision),
|
26 |
+
layer_difference=int(layer_difference),
|
27 |
+
corner_threshold=int(corner_threshold),
|
28 |
+
length_threshold=float(length_threshold),
|
29 |
+
max_iterations=int(max_iterations),
|
30 |
+
splice_threshold=int(splice_threshold),
|
31 |
+
path_precision=int(path_precision)
|
32 |
+
)
|
33 |
+
|
34 |
+
# Save the SVG string to a temporary file
|
35 |
+
temp_file = tempfile.NamedTemporaryFile(delete=False, suffix='.svg')
|
36 |
+
temp_file.write(svg_str.encode('utf-8'))
|
37 |
+
temp_file.close()
|
38 |
+
|
39 |
+
# Display the SVG in the Gradio interface and provide the download link
|
40 |
+
svg_html = f'<svg viewBox="0 0 {image.width} {image.height}">{svg_str}</svg>'
|
41 |
+
return gr.HTML(svg_html), temp_file.name
|
42 |
+
|
43 |
+
# Gradio interface
|
44 |
+
iface = gr.Blocks()
|
45 |
+
|
46 |
+
with iface:
|
47 |
+
gr.Markdown("# Convert Image to SVG Vectors")
|
48 |
+
gr.Markdown("Upload an image and customize the conversion parameters for powerful, high-quality vector results.")
|
49 |
+
|
50 |
+
with gr.Row():
|
51 |
+
image_input = gr.Image(type="pil", label="Upload Image")
|
52 |
+
color_mode_input = gr.Radio(choices=["Color", "Binary"], value="Color", label="Color Mode")
|
53 |
+
hierarchical_input = gr.Radio(choices=["Stacked", "Cutout"], value="Stacked", label="Hierarchical")
|
54 |
+
mode_input = gr.Radio(choices=["Spline", "Polygon", "None"], value="Spline", label="Mode")
|
55 |
+
|
56 |
+
with gr.Row():
|
57 |
+
filter_speckle_input = gr.Slider(minimum=1, maximum=100, value=4, step=1, label="Filter Speckle")
|
58 |
+
color_precision_input = gr.Slider(minimum=1, maximum=100, value=6, step=1, label="Color Precision")
|
59 |
+
layer_difference_input = gr.Slider(minimum=1, maximum=100, value=16, step=1, label="Layer Difference")
|
60 |
+
|
61 |
+
with gr.Row():
|
62 |
+
corner_threshold_input = gr.Slider(minimum=1, maximum=100, value=60, step=1, label="Corner Threshold")
|
63 |
+
length_threshold_input = gr.Slider(minimum=1, maximum=100, value=4.0, step=0.5, label="Length Threshold")
|
64 |
+
max_iterations_input = gr.Slider(minimum=1, maximum=100, value=10, step=1, label="Max Iterations")
|
65 |
+
|
66 |
+
with gr.Row():
|
67 |
+
splice_threshold_input = gr.Slider(minimum=1, maximum=100, value=45, step=1, label="Splice Threshold")
|
68 |
+
path_precision_input = gr.Slider(minimum=1, maximum=100, value=8, step=1, label="Path Precision")
|
69 |
+
|
70 |
+
convert_button = gr.Button("Convert Image to SVG")
|
71 |
+
svg_output = gr.HTML(label="SVG Output")
|
72 |
+
download_output = gr.File(label="Download SVG")
|
73 |
+
|
74 |
+
convert_button.click(
|
75 |
+
fn=convert_image,
|
76 |
+
inputs=[
|
77 |
+
image_input, color_mode_input, hierarchical_input, mode_input,
|
78 |
+
filter_speckle_input, color_precision_input, layer_difference_input,
|
79 |
+
corner_threshold_input, length_threshold_input, max_iterations_input,
|
80 |
+
splice_threshold_input, path_precision_input
|
81 |
+
],
|
82 |
+
outputs=[svg_output, download_output]
|
83 |
+
)
|
84 |
|
85 |
+
iface.launch()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|