svg2png / app.py
codelion's picture
Update app.py
5a11c85 verified
raw
history blame contribute delete
2.76 kB
import cairosvg
import gradio as gr
from PIL import Image
import os
import cairosvg
import xml.etree.ElementTree as ET
from PIL import Image
def convert_svg_to_png(svg_file, size_input):
"""Convert SVG to PNG with user-specified dimensions, preserving the entire content."""
# Input validation
if svg_file is None or not size_input or not size_input.strip():
return None, None, "Please upload an SVG file and specify a size."
# Read the SVG content
with open(svg_file.name, 'rb') as f:
svg_content = f.read()
# Parse the size input
try:
output_width, output_height = map(int, size_input.split('x'))
if output_width <= 0 or output_height <= 0:
raise ValueError("Width and height must be positive")
except ValueError:
return None, None, "Invalid size format. Use 'width x height' (e.g., '800x600') with positive numbers."
# Parse the SVG to handle viewBox and set width/height if missing
try:
root = ET.fromstring(svg_content)
view_box = root.get('viewBox')
if view_box and 'width' not in root.attrib and 'height' not in root.attrib:
_, _, vb_width, vb_height = map(float, view_box.split())
root.set('width', str(vb_width))
root.set('height', str(vb_height))
svg_content = ET.tostring(root, encoding='utf-8')
except ET.ParseError:
return None, None, "Invalid SVG file."
# Define output path
output_path = "./output.png"
# Convert SVG to PNG with user-specified dimensions
cairosvg.svg2png(
bytestring=svg_content,
write_to=output_path,
output_width=output_width,
output_height=output_height
)
# Load the PNG
final_image = Image.open(output_path)
return final_image, output_path, f"PNG generated at {output_width}x{output_height} pixels."
with gr.Blocks() as bl:
gr.Markdown("# SVG to PNG Converter")
with gr.Row():
with gr.Column():
svg_input = gr.File(label="Upload SVG File", file_types=[".svg"])
size_input = gr.Textbox(
label="Output Size (width x height)",
placeholder="e.g., 800x600"
)
convert_btn = gr.Button("Convert")
with gr.Column():
final_output = gr.Image(type='pil', label="Output PNG", height=800)
download_btn = gr.File(label="Download PNG")
status_output = gr.Textbox(label="Status", interactive=False)
# Connect the conversion function
convert_btn.click(
fn=convert_svg_to_png,
inputs=[svg_input, size_input],
outputs=[final_output, download_btn, status_output]
)
bl.launch()