File size: 1,615 Bytes
a66f445
 
 
 
 
 
8498e59
 
 
 
 
a66f445
 
8498e59
 
 
 
a66f445
8498e59
 
a66f445
8498e59
 
 
a66f445
8498e59
a66f445
8498e59
 
 
a66f445
8498e59
a66f445
8498e59
 
 
 
 
 
 
a66f445
8498e59
a66f445
 
 
8498e59
a66f445
 
 
 
 
8498e59
a66f445
8498e59
 
a66f445
 
 
 
 
 
 
 
 
 
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
import gradio as gr
from PIL import Image
import numpy as np
import cv2
import tempfile
import os
import uuid

# Persistent temp folder
TEMP_DIR = "/tmp/vector_outputs"
os.makedirs(TEMP_DIR, exist_ok=True)

def image_to_svg(input_image):
    # Unique filenames (avoid conflicts)
    uid = str(uuid.uuid4())
    png_path = os.path.join(TEMP_DIR, f"{uid}.png")
    svg_path = os.path.join(TEMP_DIR, f"{uid}.svg")

    # Save PNG
    input_image.save(png_path)

    # OpenCV processing
    img = cv2.imread(png_path)
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

    _, thresh = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY)

    contours, _ = cv2.findContours(
        thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE
    )

    height, width = gray.shape

    # Create SVG
    with open(svg_path, "w") as f:
        f.write(f'<svg xmlns="http://www.w3.org/2000/svg" width="{width}" height="{height}">')
        for cnt in contours:
            points = " ".join([f"{p[0][0]},{p[0][1]}" for p in cnt])
            f.write(f'<polygon points="{points}" style="fill:black;stroke:none;" />')
        f.write("</svg>")

    return png_path, svg_path


def process(image):
    return image_to_svg(image)


with gr.Blocks() as demo:
    gr.Markdown("# 🖼️ Image → Vector Converter (PNG + SVG)")

    input_image = gr.Image(type="pil", label="Upload Image")

    png_output = gr.File(label="Download PNG")
    svg_output = gr.File(label="Download SVG")

    btn = gr.Button("Convert")

    btn.click(
        fn=process,
        inputs=input_image,
        outputs=[png_output, svg_output]
    )

demo.launch()