File size: 3,083 Bytes
4a121a0
18a4938
 
 
 
a6a908a
f66d864
 
1b43408
 
 
4a121a0
1b43408
 
 
f66d864
 
 
 
a8aa56e
f66d864
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
a8aa56e
f66d864
 
 
 
 
 
 
 
a8aa56e
f66d864
 
 
07efcb2
 
f66d864
07efcb2
 
 
 
f66d864
07efcb2
 
f66d864
 
 
 
 
 
 
 
 
 
07efcb2
f66d864
 
 
 
 
 
07efcb2
f66d864
 
 
 
 
 
 
 
07efcb2
 
 
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
import cairosvg
import gradio as gr
from PIL import Image
import os
import xml.etree.ElementTree as ET

def initial_render(svg_file):
    """Render SVG at a large size for preview and cropping."""
    if svg_file is None:
        return None, None
    
    # Read the SVG content
    with open(svg_file.name, 'rb') as f:
        svg_content = f.read()
    
    # Store SVG content in a temporary file for later use
    temp_svg_path = "./temp.svg"
    with open(temp_svg_path, 'wb') as f:
        f.write(svg_content)
    
    # Initial large render
    output_path = "./initial_preview.png"
    cairosvg.svg2png(
        bytestring=svg_content,
        write_to=output_path,
        output_width=3000,  # Large initial size to capture all content
        output_height=3000
    )
    
    # Load the preview image
    preview_image = Image.open(output_path)
    return preview_image, temp_svg_path

def final_convert(svg_path, crop_box):
    """Convert SVG to PNG using user-specified crop box dimensions."""
    if svg_path is None or crop_box is None:
        return None, None
    
    # Extract crop coordinates from the crop_box dictionary
    # crop_box format: {'left': x1, 'top': y1, 'right': x2, 'bottom': y2}
    left = crop_box['left']
    top = crop_box['top']
    width = crop_box['right'] - left
    height = crop_box['bottom'] - top
    
    # Read the stored SVG content
    with open(svg_path, 'rb') as f:
        svg_content = f.read()
    
    # Final output path
    output_path = "./final_output.png"
    
    # Convert with user-specified dimensions
    cairosvg.svg2png(
        bytestring=svg_content,
        write_to=output_path,
        output_width=width,
        output_height=height,
        # Optional: adjust scale or offset if needed based on original SVG coordinates
    )
    
    # Load the final PNG
    final_image = Image.open(output_path)
    return final_image, output_path

with gr.Blocks() as bl:
    gr.Markdown("# SVG to PNG Converter with Custom Crop")
    
    with gr.Row():
        with gr.Column():
            svg_input = gr.File(label="Upload SVG File", file_types=[".svg"])
            preview_btn = gr.Button("Generate Preview")
        
        with gr.Column():
            preview_output = gr.Image(
                type='pil',
                label="Preview (Draw a box to crop)",
                interactive=True,
                tool="sketch",
                height=800
            )
            crop_btn = gr.Button("Convert with Crop")
            final_output = gr.Image(type='pil', label="Final PNG", height=800)
            download_btn = gr.File(label="Download Final PNG")
    
    # State to store the temporary SVG path
    svg_state = gr.State()
    
    # Step 1: Generate initial preview
    preview_btn.click(
        fn=initial_render,
        inputs=svg_input,
        outputs=[preview_output, svg_state]
    )
    
    # Step 2: Convert using crop box
    crop_btn.click(
        fn=final_convert,
        inputs=[svg_state, preview_output],
        outputs=[final_output, download_btn]
    )

bl.launch()