codelion commited on
Commit
f66d864
·
verified ·
1 Parent(s): 8e6acfa

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +74 -45
app.py CHANGED
@@ -4,8 +4,8 @@ from PIL import Image
4
  import os
5
  import xml.etree.ElementTree as ET
6
 
7
- def show(svg_file):
8
- # Check if no file is uploaded
9
  if svg_file is None:
10
  return None, None
11
 
@@ -13,62 +13,91 @@ def show(svg_file):
13
  with open(svg_file.name, 'rb') as f:
14
  svg_content = f.read()
15
 
16
- # Parse SVG to extract width and height
17
- try:
18
- root = ET.fromstring(svg_content)
19
- width = root.get('width')
20
- height = root.get('height')
21
- if width and height:
22
- # Remove units (like 'px') and convert to float
23
- width = float(''.join(filter(str.isdigit, width)) or width)
24
- height = float(''.join(filter(str.isdigit, height)) or height)
25
- else:
26
- width = height = None
27
- except ET.ParseError:
28
- # Handle invalid SVG
29
- width = height = None
30
 
31
- # Define output path
32
- output_path = "./test.png"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
33
 
34
- # Convert SVG to PNG with explicit size if available
35
- if width and height:
36
- cairosvg.svg2png(
37
- bytestring=svg_content,
38
- write_to=output_path,
39
- output_width=width,
40
- output_height=height
41
- )
42
- else:
43
- # Fallback to default rendering with a reasonable size
44
- cairosvg.svg2png(
45
- bytestring=svg_content,
46
- write_to=output_path,
47
- output_width=1600, # Default width if not specified
48
- output_height=1200 # Default height if not specified
49
- )
50
 
51
- # Load the PNG as a PIL image
52
- png_image = Image.open(output_path)
53
- return png_image, output_path
54
 
55
  with gr.Blocks() as bl:
56
- gr.Markdown("# SVG to PNG Converter")
57
 
58
  with gr.Row():
59
  with gr.Column():
60
  svg_input = gr.File(label="Upload SVG File", file_types=[".svg"])
61
- convert_btn = gr.Button("Convert")
62
 
63
  with gr.Column():
64
- png_output = gr.Image(type='pil', label="Converted PNG", height=800)
65
- download_btn = gr.File(label="Download PNG")
 
 
 
 
 
 
 
 
66
 
67
- # Connect the conversion function
68
- convert_btn.click(
69
- fn=show,
 
 
 
70
  inputs=svg_input,
71
- outputs=[png_output, download_btn]
 
 
 
 
 
 
 
72
  )
73
 
74
  bl.launch()
 
4
  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
 
 
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):
35
+ """Convert SVG to PNG using user-specified crop box dimensions."""
36
+ if svg_path is None or crop_box is None:
37
+ return None, None
38
+
39
+ # Extract crop coordinates from the crop_box dictionary
40
+ # crop_box format: {'left': x1, 'top': y1, 'right': x2, 'bottom': y2}
41
+ left = crop_box['left']
42
+ top = crop_box['top']
43
+ width = crop_box['right'] - left
44
+ height = crop_box['bottom'] - top
45
+
46
+ # Read the stored SVG content
47
+ with open(svg_path, 'rb') as f:
48
+ svg_content = f.read()
49
+
50
+ # Final output path
51
+ output_path = "./final_output.png"
52
 
53
+ # Convert with user-specified dimensions
54
+ cairosvg.svg2png(
55
+ bytestring=svg_content,
56
+ write_to=output_path,
57
+ output_width=width,
58
+ output_height=height,
59
+ # Optional: adjust scale or offset if needed based on original SVG coordinates
60
+ )
 
 
 
 
 
 
 
 
61
 
62
+ # Load the final PNG
63
+ final_image = Image.open(output_path)
64
+ return final_image, output_path
65
 
66
  with gr.Blocks() as bl:
67
+ gr.Markdown("# SVG to PNG Converter with Custom Crop")
68
 
69
  with gr.Row():
70
  with gr.Column():
71
  svg_input = gr.File(label="Upload SVG File", file_types=[".svg"])
72
+ preview_btn = gr.Button("Generate Preview")
73
 
74
  with gr.Column():
75
+ preview_output = gr.Image(
76
+ type='pil',
77
+ label="Preview (Draw a box to crop)",
78
+ interactive=True,
79
+ tool="sketch",
80
+ height=800
81
+ )
82
+ crop_btn = gr.Button("Convert with Crop")
83
+ final_output = gr.Image(type='pil', label="Final PNG", height=800)
84
+ download_btn = gr.File(label="Download Final PNG")
85
 
86
+ # State to store the temporary SVG path
87
+ svg_state = gr.State()
88
+
89
+ # Step 1: Generate initial preview
90
+ preview_btn.click(
91
+ fn=initial_render,
92
  inputs=svg_input,
93
+ outputs=[preview_output, svg_state]
94
+ )
95
+
96
+ # Step 2: Convert using crop box
97
+ crop_btn.click(
98
+ fn=final_convert,
99
+ inputs=[svg_state, preview_output],
100
+ outputs=[final_output, download_btn]
101
  )
102
 
103
  bl.launch()