File size: 3,733 Bytes
4a121a0 18a4938 a6a908a f66d864 1b43408 4a121a0 1b43408 f66d864 a8aa56e f66d864 a1bff88 f66d864 a8aa56e a1bff88 f66d864 a1bff88 f66d864 a8aa56e f66d864 07efcb2 a1bff88 07efcb2 f66d864 a1bff88 07efcb2 f66d864 a1bff88 f66d864 a1bff88 f66d864 07efcb2 f66d864 07efcb2 f66d864 a1bff88 f66d864 a1bff88 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 104 105 106 107 108 109 110 111 112 113 114 115 116 |
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, size_input):
"""Convert SVG to PNG using either crop box or user-specified dimensions."""
if svg_path is None:
return None, None
# Read the stored SVG content
with open(svg_path, 'rb') as f:
svg_content = f.read()
# Final output path
output_path = "./final_output.png"
# Determine output dimensions
if size_input and size_input.strip(): # Check if size input is provided
try:
width, height = map(int, size_input.split('x'))
if width <= 0 or height <= 0:
raise ValueError("Width and height must be positive")
except ValueError:
return gr.Warning("Invalid size format. Use 'width x height' (e.g., '800x600')"), None
elif crop_box and 'left' in crop_box: # Use crop box if size input is empty
left = crop_box['left']
top = crop_box['top']
width = crop_box['right'] - left
height = crop_box['bottom'] - top
else:
# Fallback if neither is provided (shouldn't happen with UI flow)
width, height = 2000, 2000
# Convert SVG to PNG with determined dimensions
cairosvg.svg2png(
bytestring=svg_content,
write_to=output_path,
output_width=width,
output_height=height
)
# 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 or Size")
with gr.Row():
with gr.Column():
svg_input = gr.File(label="Upload SVG File", file_types=[".svg"])
preview_btn = gr.Button("Generate Preview")
size_input = gr.Textbox(
label="Output Size (width x height)",
placeholder="e.g., 800x600 (optional, overrides crop)"
)
with gr.Column():
preview_output = gr.Image(
type='pil',
label="Preview (Draw a box to crop if no size specified)",
interactive=True,
tool="sketch",
height=800
)
crop_btn = gr.Button("Convert")
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 or specified size
crop_btn.click(
fn=final_convert,
inputs=[svg_state, preview_output, size_input],
outputs=[final_output, download_btn]
)
bl.launch() |