|
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.""" |
|
|
|
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." |
|
|
|
|
|
with open(svg_file.name, 'rb') as f: |
|
svg_content = f.read() |
|
|
|
|
|
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." |
|
|
|
|
|
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." |
|
|
|
|
|
output_path = "./output.png" |
|
|
|
|
|
cairosvg.svg2png( |
|
bytestring=svg_content, |
|
write_to=output_path, |
|
output_width=output_width, |
|
output_height=output_height |
|
) |
|
|
|
|
|
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) |
|
|
|
|
|
convert_btn.click( |
|
fn=convert_svg_to_png, |
|
inputs=[svg_input, size_input], |
|
outputs=[final_output, download_btn, status_output] |
|
) |
|
|
|
bl.launch() |