Update app.py
Browse files
app.py
CHANGED
@@ -5,112 +5,56 @@ import os
|
|
5 |
import xml.etree.ElementTree as ET
|
6 |
|
7 |
def initial_render(svg_file):
|
8 |
-
"""Render SVG at a large size for preview and cropping."""
|
9 |
if svg_file is None:
|
10 |
return None, None
|
11 |
-
|
12 |
-
# Read the SVG content
|
13 |
with open(svg_file.name, 'rb') as f:
|
14 |
svg_content = f.read()
|
15 |
-
|
16 |
-
# Store SVG content in a temporary file for later use
|
17 |
temp_svg_path = "./temp.svg"
|
18 |
with open(temp_svg_path, 'wb') as f:
|
19 |
f.write(svg_content)
|
20 |
-
|
21 |
-
# Initial large render
|
22 |
output_path = "./initial_preview.png"
|
23 |
-
cairosvg.svg2png(
|
24 |
-
bytestring=svg_content,
|
25 |
-
write_to=output_path,
|
26 |
-
output_width=3000, # Large initial size to capture all content
|
27 |
-
output_height=3000
|
28 |
-
)
|
29 |
-
|
30 |
-
# Load the preview image
|
31 |
preview_image = Image.open(output_path)
|
32 |
return preview_image, temp_svg_path
|
33 |
|
34 |
def final_convert(svg_path, crop_box, size_input):
|
35 |
-
"""Convert SVG to PNG using either crop box or user-specified dimensions."""
|
36 |
if svg_path is None:
|
37 |
return None, None
|
38 |
-
|
39 |
-
# Read the stored SVG content
|
40 |
with open(svg_path, 'rb') as f:
|
41 |
svg_content = f.read()
|
42 |
-
|
43 |
-
# Final output path
|
44 |
output_path = "./final_output.png"
|
45 |
-
|
46 |
-
# Determine output dimensions
|
47 |
-
if size_input and size_input.strip(): # Check if size input is provided
|
48 |
try:
|
49 |
width, height = map(int, size_input.split('x'))
|
50 |
if width <= 0 or height <= 0:
|
51 |
raise ValueError("Width and height must be positive")
|
52 |
except ValueError:
|
53 |
return gr.Warning("Invalid size format. Use 'width x height' (e.g., '800x600')"), None
|
54 |
-
elif crop_box and 'left' in crop_box:
|
55 |
left = crop_box['left']
|
56 |
top = crop_box['top']
|
57 |
width = crop_box['right'] - left
|
58 |
height = crop_box['bottom'] - top
|
59 |
else:
|
60 |
-
# Fallback if neither is provided (shouldn't happen with UI flow)
|
61 |
width, height = 2000, 2000
|
62 |
-
|
63 |
-
# Convert SVG to PNG with determined dimensions
|
64 |
-
cairosvg.svg2png(
|
65 |
-
bytestring=svg_content,
|
66 |
-
write_to=output_path,
|
67 |
-
output_width=width,
|
68 |
-
output_height=height
|
69 |
-
)
|
70 |
-
|
71 |
-
# Load the final PNG
|
72 |
final_image = Image.open(output_path)
|
73 |
return final_image, output_path
|
74 |
|
75 |
with gr.Blocks() as bl:
|
76 |
gr.Markdown("# SVG to PNG Converter with Custom Crop or Size")
|
77 |
-
|
78 |
with gr.Row():
|
79 |
with gr.Column():
|
80 |
svg_input = gr.File(label="Upload SVG File", file_types=[".svg"])
|
81 |
preview_btn = gr.Button("Generate Preview")
|
82 |
-
size_input = gr.Textbox(
|
83 |
-
label="Output Size (width x height)",
|
84 |
-
placeholder="e.g., 800x600 (optional, overrides crop)"
|
85 |
-
)
|
86 |
-
|
87 |
with gr.Column():
|
88 |
-
preview_output = gr.Image(
|
89 |
-
type='pil',
|
90 |
-
label="Preview (Draw a box to crop if no size specified)",
|
91 |
-
interactive=True,
|
92 |
-
tool="sketch",
|
93 |
-
height=800
|
94 |
-
)
|
95 |
crop_btn = gr.Button("Convert")
|
96 |
final_output = gr.Image(type='pil', label="Final PNG", height=800)
|
97 |
download_btn = gr.File(label="Download Final PNG")
|
98 |
-
|
99 |
-
# State to store the temporary SVG path
|
100 |
svg_state = gr.State()
|
101 |
-
|
102 |
-
|
103 |
-
preview_btn.click(
|
104 |
-
fn=initial_render,
|
105 |
-
inputs=svg_input,
|
106 |
-
outputs=[preview_output, svg_state]
|
107 |
-
)
|
108 |
-
|
109 |
-
# Step 2: Convert using crop box or specified size
|
110 |
-
crop_btn.click(
|
111 |
-
fn=final_convert,
|
112 |
-
inputs=[svg_state, preview_output, size_input],
|
113 |
-
outputs=[final_output, download_btn]
|
114 |
-
)
|
115 |
|
116 |
bl.launch()
|
|
|
5 |
import xml.etree.ElementTree as ET
|
6 |
|
7 |
def initial_render(svg_file):
|
|
|
8 |
if svg_file is None:
|
9 |
return None, None
|
|
|
|
|
10 |
with open(svg_file.name, 'rb') as f:
|
11 |
svg_content = f.read()
|
|
|
|
|
12 |
temp_svg_path = "./temp.svg"
|
13 |
with open(temp_svg_path, 'wb') as f:
|
14 |
f.write(svg_content)
|
|
|
|
|
15 |
output_path = "./initial_preview.png"
|
16 |
+
cairosvg.svg2png(bytestring=svg_content, write_to=output_path, output_width=3000, output_height=3000)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
17 |
preview_image = Image.open(output_path)
|
18 |
return preview_image, temp_svg_path
|
19 |
|
20 |
def final_convert(svg_path, crop_box, size_input):
|
|
|
21 |
if svg_path is None:
|
22 |
return None, None
|
|
|
|
|
23 |
with open(svg_path, 'rb') as f:
|
24 |
svg_content = f.read()
|
|
|
|
|
25 |
output_path = "./final_output.png"
|
26 |
+
if size_input and size_input.strip():
|
|
|
|
|
27 |
try:
|
28 |
width, height = map(int, size_input.split('x'))
|
29 |
if width <= 0 or height <= 0:
|
30 |
raise ValueError("Width and height must be positive")
|
31 |
except ValueError:
|
32 |
return gr.Warning("Invalid size format. Use 'width x height' (e.g., '800x600')"), None
|
33 |
+
elif crop_box and 'left' in crop_box:
|
34 |
left = crop_box['left']
|
35 |
top = crop_box['top']
|
36 |
width = crop_box['right'] - left
|
37 |
height = crop_box['bottom'] - top
|
38 |
else:
|
|
|
39 |
width, height = 2000, 2000
|
40 |
+
cairosvg.svg2png(bytestring=svg_content, write_to=output_path, output_width=width, output_height=height)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
41 |
final_image = Image.open(output_path)
|
42 |
return final_image, output_path
|
43 |
|
44 |
with gr.Blocks() as bl:
|
45 |
gr.Markdown("# SVG to PNG Converter with Custom Crop or Size")
|
|
|
46 |
with gr.Row():
|
47 |
with gr.Column():
|
48 |
svg_input = gr.File(label="Upload SVG File", file_types=[".svg"])
|
49 |
preview_btn = gr.Button("Generate Preview")
|
50 |
+
size_input = gr.Textbox(label="Output Size (width x height)", placeholder="e.g., 800x600 (optional, overrides crop)")
|
|
|
|
|
|
|
|
|
51 |
with gr.Column():
|
52 |
+
preview_output = gr.Image(type='pil', label="Preview (Draw a box to crop if no size specified)", interactive=True, tool="sketch", height=800)
|
|
|
|
|
|
|
|
|
|
|
|
|
53 |
crop_btn = gr.Button("Convert")
|
54 |
final_output = gr.Image(type='pil', label="Final PNG", height=800)
|
55 |
download_btn = gr.File(label="Download Final PNG")
|
|
|
|
|
56 |
svg_state = gr.State()
|
57 |
+
preview_btn.click(fn=initial_render, inputs=svg_input, outputs=[preview_output, svg_state])
|
58 |
+
crop_btn.click(fn=final_convert, inputs=[svg_state, preview_output, size_input], outputs=[final_output, download_btn])
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
59 |
|
60 |
bl.launch()
|