Convert and Manipulate SVG Files with Python
SVG (Scalable Vector Graphics) is the standard vector format for the web. Python provides tools to convert SVG to PNG/PDF, edit content, and generate SVG programmatically.
Installation
pip install cairosvg svglib reportlab lxml
Convert SVG to PNG with cairosvg
import cairosvg
# SVG to PNG at 300 DPI
cairosvg.svg2png(
url="icon.svg",
write_to="icon.png",
output_width=512,
output_height=512,
dpi=300
)
# From SVG string
svg_code = '<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100"><circle cx="50" cy="50" r="40" fill="blue"/></svg>'
cairosvg.svg2png(bytestring=svg_code.encode(), write_to="circle.png")
print("PNG generated")
Convert SVG to PDF
import cairosvg
cairosvg.svg2pdf(
url="diagram.svg",
write_to="diagram.pdf",
output_width=595, # A4 in points
output_height=842
)
print("PDF generated: diagram.pdf")
Convert SVG to WebP and Other Formats
import cairosvg
from PIL import Image
import io
def svg_to_format(svg_path, output, fmt="webp", width=800):
png_bytes = cairosvg.svg2png(url=svg_path, output_width=width)
img = Image.open(io.BytesIO(png_bytes))
img.save(output, format=fmt.upper())
print(f"SVG converted to {fmt.upper()}: {output}")
svg_to_format("logo.svg", "logo.webp", "webp", 1024)
svg_to_format("logo.svg", "logo.jpg", "jpeg", 800)
Edit SVG with lxml
from lxml import etree
def change_svg_color(input_file, output_file, old_color, new_color):
tree = etree.parse(input_file)
root = tree.getroot()
for elem in root.iter():
if elem.get('fill') == old_color:
elem.set('fill', new_color)
style = elem.get('style', '')
if f'fill:{old_color}' in style:
elem.set('style', style.replace(f'fill:{old_color}', f'fill:{new_color}'))
tree.write(output_file, pretty_print=True, xml_declaration=True, encoding='utf-8')
print(f"Color changed: {old_color} -> {new_color}")
change_svg_color("icon.svg", "icon_red.svg", "#0000ff", "#ff0000")
Resize SVG
from lxml import etree
def resize_svg(input_file, output_file, new_width, new_height):
tree = etree.parse(input_file)
root = tree.getroot()
orig_w = float(root.get('width', '100').replace('px',''))
orig_h = float(root.get('height','100').replace('px',''))
root.set('width', str(new_width))
root.set('height', str(new_height))
if not root.get('viewBox'):
root.set('viewBox', f'0 0 {orig_w} {orig_h}')
tree.write(output_file, pretty_print=True, encoding='utf-8')
print(f"Resized: {orig_w}x{orig_h} -> {new_width}x{new_height}")
resize_svg("icon.svg", "icon_256.svg", 256, 256)
Generate SVG from Python
def create_bar_chart_svg(data, output, width=400, height=300):
max_val = max(data.values())
bar_w = (width - 60) // len(data)
lines = [
f'<svg xmlns="http://www.w3.org/2000/svg" width="{width}" height="{height}">',
f'<rect width="{width}" height="{height}" fill="#f8f8f8" stroke="#ddd"/>',
f'<text x="{width//2}" y="25" text-anchor="middle" font-size="14" fill="#333">Bar Chart</text>',
]
colors = ["#4a9eff", "#ff6b6b", "#51cf66", "#ffd43b", "#cc5de8"]
for i, (label, value) in enumerate(data.items()):
bh = int((value / max_val) * (height - 80))
bx = 30 + i * bar_w
by = height - 40 - bh
c = colors[i % len(colors)]
lines.append(f'<rect x="{bx}" y="{by}" width="{bar_w-4}" height="{bh}" fill="{c}" rx="3"/>')
lines.append(f'<text x="{bx+bar_w//2-2}" y="{height-20}" text-anchor="middle" font-size="10" fill="#555">{label}</text>')
lines.append(f'<text x="{bx+bar_w//2-2}" y="{by-4}" text-anchor="middle" font-size="10" fill="#333">{value}</text>')
lines.append('</svg>')
with open(output, 'w', encoding='utf-8') as f:
f.write('\n'.join(lines))
print(f"SVG created: {output}")
create_bar_chart_svg({"Jan":120,"Feb":85,"Mar":200,"Apr":150,"May":175}, "sales.svg")
Batch Conversion
import cairosvg
from pathlib import Path
def batch_convert_svgs(folder, output_fmt="png", dpi=96):
svgs = list(Path(folder).glob("*.svg"))
for i, svg in enumerate(svgs, 1):
out = svg.with_suffix(f".{output_fmt}")
try:
if output_fmt == "pdf":
cairosvg.svg2pdf(url=str(svg), write_to=str(out))
else:
cairosvg.svg2png(url=str(svg), write_to=str(out), dpi=dpi)
print(f" [{i}/{len(svgs)}] {svg.name} -> {out.name}")
except Exception as e:
print(f" [{i}] ERROR {svg.name}: {e}")
batch_convert_svgs("icons/", "png", 144)
Additional Resource
For converting SVG files to PNG, PDF or WebP without any coding, use KaijuConverter — free and no registration required.
Related conversions
Most teams that read this guide convert images in one of these directions: