Spaces:
Sleeping
Sleeping
File size: 5,850 Bytes
9e835dd 07ece8d 9e835dd 44bf299 c8e76d3 9e835dd 44bf299 9e835dd abdd93e 07ece8d c8e76d3 fe88f1f 9e835dd fe88f1f c8e76d3 fe88f1f 0fddbf9 fe88f1f 07ece8d c8e76d3 fe88f1f 9e835dd c8e76d3 fe88f1f c8e76d3 fe88f1f 9e835dd 07ece8d 44bf299 0fddbf9 44bf299 0fddbf9 44bf299 9e835dd 07ece8d 9e835dd 44bf299 07ece8d 44bf299 07ece8d 3b263fa c8e76d3 3b263fa 07ece8d 9e835dd 07ece8d 44bf299 07ece8d 9e835dd 44bf299 07ece8d 44bf299 07ece8d 44bf299 07ece8d 9e835dd 44bf299 0fddbf9 07ece8d 0fddbf9 07ece8d 0fddbf9 07ece8d abdd93e |
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 |
import gradio as gr
import vtracer
import os
import tempfile
def image_to_svg(image, colormode, hierarchical, filter_speckle, color_precision, layer_difference, mode, corner_threshold, length_threshold, splice_threshold, path_precision):
"""
Converts an input image to an SVG string using vtracer.
This function is triggered automatically when any of the input controls change.
It now includes robust error handling to prevent the app from freezing.
"""
if image is None:
return None, "Upload an image to see the SVG preview and code.", None
input_path = image
# Create a persistent temporary file that Gradio can access.
with tempfile.NamedTemporaryFile(delete=False, suffix=".svg", mode='w', encoding='utf-8') as temp_output_file:
output_path = temp_output_file.name
try:
# vtracer conversion call with all parameters from the UI.
vtracer.convert_image_to_svg_py(
input_path,
output_path,
colormode=colormode.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),
splice_threshold=int(splice_threshold),
path_precision=int(path_precision),
max_iterations=10
)
# If successful, read the generated SVG content to display.
with open(output_path, "r", encoding='utf-8') as f:
svg_content = f.read()
return output_path, svg_content, output_path
# **THE FIX for Error Handling:**
# Catch any exception from the vtracer process.
except Exception as e:
# Create a user-friendly error message.
error_message = (
f"⚠️ Conversion Failed\n\n"
f"An error occurred in the backend. This can happen with certain image types or extreme parameter values.\n\n"
f"Please try adjusting the settings or use a different image.\n\n"
f"Details: {str(e)}"
)
# Return clean outputs and display the error message in the code block.
# This prevents the app from getting stuck.
return None, error_message, None
# --- Gradio User Interface ---
with gr.Blocks(theme=gr.themes.Soft(primary_hue="blue")) as demo:
with gr.Row():
with gr.Column(scale=1):
image_input = gr.Image(type="filepath", label="Upload Your Image", sources=["upload", "clipboard"])
with gr.Column(scale=2):
gr.Markdown(
"""
# IMG2SVG: Real-time SVG Converter
This application converts raster images into clean, scalable vector graphics (SVG).
**How to use:**
1. Upload an image.
2. Adjust the settings in the control panel below.
3. The SVG preview updates automatically when you change a setting.
"""
)
with gr.Row(variant="panel"):
with gr.Column(scale=1):
gr.Markdown("### Control Panel")
with gr.Group():
gr.Markdown("#### Clustering")
colormode = gr.Radio(["Color", "B/W"], value="Color", label="Color Mode")
hierarchical = gr.Radio(["Stacked", "Cutout"], value="Stacked", label="Hierarchical Mode")
filter_speckle = gr.Slider(0, 128, value=4, step=1, label="Filter Speckle (Cleaner)")
# **THE FIX for Parameter Range:**
# The vtracer backend panics if color_precision is 0.
# The valid range is 1-8. This slider now enforces that constraint.
color_precision = gr.Slider(1, 8, value=6, step=1, label="Color Precision (More accurate)")
layer_difference = gr.Slider(0, 128, value=16, step=1, label="Gradient Step (Less layers)")
with gr.Group():
gr.Markdown("#### Curve Fitting")
mode = gr.Radio(["Spline", "Polygon", "Pixel"], value="Spline", label="Mode")
corner_threshold = gr.Slider(0, 180, value=60, step=1, label="Corner Threshold (Smoother)")
length_threshold = gr.Slider(0, 10, value=4.0, step=0.5, label="Segment Length (More coarse)")
splice_threshold = gr.Slider(0, 180, value=45, step=1, label="Splice Threshold (Less accurate)")
path_precision = gr.Slider(1, 8, value=3, step=1, label="Path Precision")
with gr.Column(scale=2):
gr.Markdown("### Result")
with gr.Tabs():
with gr.TabItem("SVG Preview"):
svg_image_output = gr.Image(label="Live SVG Preview", interactive=False)
with gr.TabItem("SVG Code"):
svg_text_output = gr.Code(label="Generated SVG Code", language="html", interactive=False)
svg_file_output = gr.File(label="Download SVG")
all_inputs = [
image_input, colormode, hierarchical, filter_speckle, color_precision,
layer_difference, mode, corner_threshold, length_threshold, splice_threshold, path_precision
]
all_outputs = [svg_file_output, svg_text_output, svg_image_output]
for slider in [filter_speckle, color_precision, layer_difference, corner_threshold, length_threshold, splice_threshold, path_precision]:
slider.release(fn=image_to_svg, inputs=all_inputs, outputs=all_outputs)
for component in [image_input, colormode, hierarchical, mode]:
component.change(fn=image_to_svg, inputs=all_inputs, outputs=all_outputs)
demo.launch() |