Spaces:
Runtime error
Runtime error
| import gradio as gr | |
| import vtracer | |
| import os | |
| from svglib.svglib import svg2rlg | |
| from reportlab.graphics import renderPDF | |
| import subprocess | |
| def convert_svg_to_ai(svg_path): | |
| # SVG๋ฅผ PDF๋ก ๋จผ์ ๋ณํ | |
| drawing = svg2rlg(svg_path) | |
| pdf_path = svg_path.replace('.svg', '.pdf') | |
| renderPDF.drawToFile(drawing, pdf_path) | |
| # PDF๋ฅผ AI๋ก ๋ณํ | |
| ai_path = svg_path.replace('.svg', '.ai') | |
| subprocess.run(['gs', '-dNOPAUSE', '-dBATCH', '-sDEVICE=pdfwrite', | |
| '-sOutputFile=' + ai_path, pdf_path]) | |
| # ์์ PDF ํ์ผ ์ญ์ | |
| os.remove(pdf_path) | |
| return ai_path | |
| def convert_to_vector( | |
| image, | |
| save_svg, | |
| save_ai, | |
| colormode="color", | |
| hierarchical="stacked", | |
| mode="spline", | |
| filter_speckle=4, | |
| color_precision=6, | |
| layer_difference=16, | |
| corner_threshold=60, | |
| length_threshold=4.0, | |
| max_iterations=10, | |
| splice_threshold=45, | |
| path_precision=3 | |
| ): | |
| if not (save_svg or save_ai): | |
| return None, None, None # ๋ ๋ค ์ ํ๋์ง ์์ ๊ฒฝ์ฐ | |
| input_path = "temp_input.jpg" | |
| svg_path = "svg_output.svg" | |
| outputs = [] | |
| preview = None | |
| # ์ ๋ ฅ ์ด๋ฏธ์ง๋ฅผ ์์ ํ์ผ๋ก ์ ์ฅ | |
| image.save(input_path) | |
| # VTracer๋ฅผ ์ฌ์ฉํ์ฌ ์ด๋ฏธ์ง๋ฅผ SVG๋ก ๋ณํ | |
| vtracer.convert_image_to_svg_py( | |
| input_path, | |
| svg_path, | |
| colormode=colormode, | |
| hierarchical=hierarchical, | |
| mode=mode, | |
| 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) | |
| ) | |
| # SVG ํ์ผ ์ฒ๋ฆฌ | |
| if save_svg: | |
| with open(svg_path, "r") as f: | |
| svg_content = f.read() | |
| preview = gr.HTML(f'<svg viewBox="0 0 {image.width} {image.height}">{svg_content}</svg>') | |
| outputs.append(svg_path) | |
| # AI ํ์ผ ์ฒ๋ฆฌ | |
| if save_ai: | |
| ai_path = convert_svg_to_ai(svg_path) | |
| outputs.append(ai_path) | |
| if not save_svg: # SVG๊ฐ ์ ํ๋์ง ์์๋ค๋ฉด ์์ ํ์ผ ์ญ์ | |
| os.remove(svg_path) | |
| return preview, outputs[0] if outputs else None, outputs[1] if len(outputs) > 1 else None | |
| css = """ | |
| #col-container { | |
| margin: 0 auto; | |
| max-width: 960px; | |
| } | |
| .generate-btn { | |
| background: linear-gradient(90deg, #4B79A1 0%, #283E51 100%) !important; | |
| border: none !important; | |
| color: white !important; | |
| } | |
| .generate-btn:hover { | |
| transform: translateY(-2px); | |
| box-shadow: 0 5px 15px rgba(0,0,0,0.2); | |
| } | |
| """ | |
| # Gradio ์ธํฐํ์ด์ค ์ ์ | |
| with gr.Blocks(css=css) as app: | |
| with gr.Column(elem_id="col-container"): | |
| gr.HTML(""" | |
| <div style="text-align: center;"> | |
| <h2>Image to Vector Converter โก</h2> | |
| <p>Converts raster images (JPG, PNG, WEBP) to vector graphics (SVG, AI).</p> | |
| </div> | |
| """) | |
| with gr.Row(): | |
| with gr.Column(): | |
| image_input = gr.Image(type="pil", label="Upload Image") | |
| with gr.Row(): | |
| save_svg = gr.Checkbox(value=True, label="Save as SVG") | |
| save_ai = gr.Checkbox(value=False, label="Save as AI") | |
| with gr.Accordion("Advanced Settings", open=False): | |
| with gr.Accordion("Clustering", open=False): | |
| colormode = gr.Radio([("COLOR","color"),("B/W", "binary")], value="color", label="Color Mode", show_label=False) | |
| filter_speckle = gr.Slider(0, 128, value=4, step=1, label="Filter Speckle", info="Cleaner") | |
| color_precision = gr.Slider(1, 8, value=6, step=1, label="Color Precision", info="More accurate") | |
| layer_difference = gr.Slider(0, 128, value=16, step=1, label="Gradient Step", info="Less layers") | |
| hierarchical = gr.Radio([("STACKED","stacked"), ("CUTOUT","cutout")], value="stacked", label="Hierarchical Mode",show_label=False) | |
| with gr.Accordion("Curve Fitting", open=False): | |
| mode = gr.Radio([("SPLINE","spline"),("POLYGON", "polygon"), ("PIXEL","none")], value="spline", label="Mode", show_label=False) | |
| corner_threshold = gr.Slider(0, 180, value=60, step=1, label="Corner Threshold", info="Smoother") | |
| length_threshold = gr.Slider(3.5, 10, value=4.0, step=0.1, label="Segment Length", info="More coarse") | |
| splice_threshold = gr.Slider(0, 180, value=45, step=1, label="Splice Threshold", info="Less accurate") | |
| max_iterations = gr.Slider(1, 20, value=10, step=1, label="Max Iterations", visible=False) | |
| path_precision = gr.Slider(1, 10, value=3, step=1, label="Path Precision", visible=False) | |
| output_text = gr.Textbox(label="Selected Mode", visible=False) | |
| with gr.Row(): | |
| clear_button = gr.Button("Clear") | |
| convert_button = gr.Button("โจ Convert", variant='primary', elem_classes=["generate-btn"]) | |
| with gr.Column(): | |
| preview = gr.HTML(label="Preview") | |
| svg_output = gr.File(label="SVG Output", visible=True) | |
| ai_output = gr.File(label="AI Output", visible=True) | |
| examples = [ | |
| "examples/11.jpg", | |
| "examples/02.jpg", | |
| "examples/03.jpg", | |
| ] | |
| gr.Examples( | |
| examples=examples, | |
| fn=convert_to_vector, | |
| inputs=[ | |
| image_input, | |
| save_svg, | |
| save_ai | |
| ], | |
| outputs=[preview, svg_output, ai_output], | |
| cache_examples=False, | |
| run_on_click=True | |
| ) | |
| # ์ด๋ฒคํธ ํธ๋ค๋ฌ | |
| def clear_inputs(): | |
| return [None] * 12 | |
| def update_output_visibility(save_svg, save_ai): | |
| return gr.update(visible=save_svg), gr.update(visible=save_ai) | |
| # ์ฒดํฌ๋ฐ์ค ์ํ์ ๋ฐ๋ฅธ ์ถ๋ ฅ ํ์ผ ์ปดํฌ๋ํธ ํ์/์จ๊น | |
| save_svg.change( | |
| update_output_visibility, | |
| inputs=[save_svg, save_ai], | |
| outputs=[svg_output, ai_output] | |
| ) | |
| save_ai.change( | |
| update_output_visibility, | |
| inputs=[save_svg, save_ai], | |
| outputs=[svg_output, ai_output] | |
| ) | |
| # ๋ณํ ๋ฒํผ ํด๋ฆญ ์ด๋ฒคํธ | |
| convert_button.click( | |
| convert_to_vector, | |
| inputs=[ | |
| image_input, | |
| save_svg, | |
| save_ai, | |
| colormode, | |
| hierarchical, | |
| mode, | |
| filter_speckle, | |
| color_precision, | |
| layer_difference, | |
| corner_threshold, | |
| length_threshold, | |
| max_iterations, | |
| splice_threshold, | |
| path_precision | |
| ], | |
| outputs=[preview, svg_output, ai_output] | |
| ) | |
| # Clear ๋ฒํผ ์ด๋ฒคํธ | |
| clear_button.click( | |
| clear_inputs, | |
| outputs=[ | |
| image_input, | |
| colormode, | |
| hierarchical, | |
| mode, | |
| filter_speckle, | |
| color_precision, | |
| layer_difference, | |
| corner_threshold, | |
| length_threshold, | |
| max_iterations, | |
| splice_threshold, | |
| path_precision | |
| ] | |
| ) | |
| app.launch(debug=True) |