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 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'
{svg_str}
') # 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()