File size: 6,576 Bytes
67f1b4c 3fa54b5 d541579 3fa54b5 91595f2 3fa54b5 91595f2 3fa54b5 91595f2 3fa54b5 91595f2 3fa54b5 91595f2 3fa54b5 3074852 91595f2 bbf7bd0 91595f2 3074852 91595f2 |
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 127 128 129 130 131 132 133 134 135 136 137 |
import os
os.system("pip uninstall -y gradio")
os.system("pip install gradio>=4.44.1")
import io
import gradio as gr
from PIL import Image
import vtracer
import tempfile
def convert_image(image, color_mode, hierarchical, mode, filter_speckle,
color_precision, layer_difference, corner_threshold,
length_threshold, max_iterations, splice_threshold, path_precision):
"""Converts an image to SVG using vtracer with customizable parameters."""
if image is None:
# Handle case where no image is uploaded yet, or it's cleared.
# You might want to return empty/default outputs or raise a Gradio error.
# For simplicity, returning None which might clear the outputs or show placeholders.
# Depending on Gradio version, this might need more graceful handling.
return None, None
# Convert Gradio image to bytes for vtracer compatibility
img_byte_array = io.BytesIO()
image.save(img_byte_array, format='PNG') # Ensure input image is PIL, format can be inferred by PIL
img_bytes = img_byte_array.getvalue()
# Perform the conversion
svg_str = vtracer.convert_raw_image_to_svg(
img_bytes,
# img_format='png', # vtracer can often infer this, but specifying is safer
colormode=color_mode.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),
max_iterations=int(max_iterations),
splice_threshold=int(splice_threshold),
path_precision=int(path_precision)
)
# Save the SVG string to a temporary file
# It's crucial that this temp file is not deleted immediately
# so Gradio's File component can serve it.
# NamedTemporaryFile needs to be kept open or its name stored carefully.
# A simpler approach for HF Spaces might be to write to a known path if persistence across calls isn't an issue,
# but NamedTemporaryFile with delete=False is generally fine.
temp_file = tempfile.NamedTemporaryFile(delete=False, suffix='.svg', mode='w', encoding='utf-8')
temp_file.write(svg_str)
temp_file.close() # Close the file handle, but the file itself remains due to delete=False
# For gr.HTML, it's often better to pass the full SVG string.
# vtracer usually produces a full SVG document including <svg> tags.
# If image is None initially, image.width and image.height would cause an error.
# The viewBox construction you had is fine if svg_str is just the inner content.
# If svg_str is a full SVG, just use gr.HTML(svg_str).
# Assuming svg_str is a full SVG document:
html_output = gr.HTML(svg_str)
# If you want to ensure a specific viewBox based on original image for the HTML display:
# html_output = gr.HTML(f'<div style="width:{image.width}px; height:{image.height}px; overflow:auto;"><svg viewBox="0 0 {image.width} {image.height}">{svg_str}</svg></div>')
# However, simply `gr.HTML(svg_str)` is usually sufficient if vtracer provides proper width/height in the SVG.
return html_output, temp_file.name
# Gradio interface
iface = gr.Blocks()
with iface:
gr.Markdown("# Hepzeka.com - Resmi SVG ye Dönüştür") # Using Markdown for title
gr.Markdown("Bir resim yükleyin ve dönüştürme parametrelerini ihtiyacınıza göre özelleştirin.") # Using Markdown for description
with gr.Row():
with gr.Column(scale=1):
image_input = gr.Image(type="pil", label="Upload Image")
color_mode_input = gr.Radio(choices=["Color", "Binary"], value="Color", label="Color Mode")
hierarchical_input = gr.Radio(choices=["Stacked", "Cutout"], value="Stacked", label="Hierarchical")
mode_input = gr.Radio(choices=["Spline", "Polygon", "None"], value="Spline", label="Mode")
filter_speckle_input = gr.Slider(minimum=1, maximum=10, value=4, step=1, label="Filter Speckle")
color_precision_input = gr.Slider(minimum=1, maximum=8, value=6, step=1, label="Color Precision")
layer_difference_input = gr.Slider(minimum=1, maximum=32, value=16, step=1, label="Layer Difference")
corner_threshold_input = gr.Slider(minimum=10, maximum=90, value=60, step=1, label="Corner Threshold")
length_threshold_input = gr.Slider(minimum=3.5, maximum=10, value=4.0, step=0.5, label="Length Threshold")
max_iterations_input = gr.Slider(minimum=1, maximum=20, value=10, step=1, label="Max Iterations")
splice_threshold_input = gr.Slider(minimum=10, maximum=90, value=45, step=1, label="Splice Threshold")
path_precision_input = gr.Slider(minimum=1, maximum=10, value=8, step=1, label="Path Precision")
submit_button = gr.Button("Convert to SVG")
with gr.Column(scale=1):
svg_output_display = gr.HTML(label="SVG Output")
svg_download_link = gr.File(label="Download SVG")
inputs_list = [
image_input,
color_mode_input,
hierarchical_input,
mode_input,
filter_speckle_input,
color_precision_input,
layer_difference_input,
corner_threshold_input,
length_threshold_input,
max_iterations_input,
splice_threshold_input,
path_precision_input
]
outputs_list = [
svg_output_display,
svg_download_link
]
# Using gr.Interface() inside gr.Blocks is one way,
# but for more control with Blocks, you typically define event listeners.
# However, your original structure with gr.Interface is fine.
# To make it more "Blocks-idiomatic" with the defined components:
submit_button.click(
fn=convert_image,
inputs=inputs_list,
outputs=outputs_list
)
# If you prefer to keep your original gr.Interface structure:
# (Comment out the submit_button.click above and uncomment the gr.Interface below)
# gr.Interface(
# fn=convert_image,
# inputs=inputs_list, # or define them inline as you had
# outputs=outputs_list, # or define them inline
# # title and description can be handled by gr.Markdown elements at the top if using Blocks for layout
# )
# Launch the interface
# For Hugging Face Spaces, share=True is not needed and can sometimes cause issues.
# Spaces handles the public URL.
iface.launch()
|