Spaces:
Sleeping
Sleeping
Download app0.py from luizC/Vectorizer-AI-To-match-Image: direct link, hf CLI and curl.
- Browser
- Download file 6.58 kB
-
https://huggingface.co/spaces/luizC/Vectorizer-AI-To-match-Image/resolve/main/app0.py
- Command line
-
hf download hf://spaces/luizC/Vectorizer-AI-To-match-Image/app0.py
-
curl -L -o app0.py https://huggingface.co/spaces/luizC/Vectorizer-AI-To-match-Image/resolve/main/app0.py
6.58 kB
| 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() | |