Python中如何将SVG渲染为指定尺寸PNG?解决裁剪问题
解决SVG转PNG尺寸匹配问题的可行方案
方案1:读取SVG原生尺寸计算精准缩放比例
- 先通过svglib获取SVG的原生宽高,再结合目标PNG尺寸计算等比例缩放值,避免裁剪:
from svglib.svglib import svg2rlg from reportlab.graphics import renderPM from PIL import Image # 获取SVG原生尺寸 drawing = svg2rlg("reference.svg") svg_width, svg_height = drawing.width, drawing.height # 获取目标PNG尺寸 png_img = Image.open("comparison.png") png_w, png_h = png_img.size # 计算安全缩放比例(取宽高缩放比的最小值) scale_x = png_w / svg_width scale_y = png_h / svg_height renderscale = min(scale_x, scale_y) # 渲染SVG并补全尺寸到目标PNG大小 rendered_png = renderPM.drawToPIL(drawing, dpi=96, scaling=renderscale) final_img = Image.new("RGBA", (png_w, png_h), (255,255,255,255)) offset = ((png_w - rendered_png.width)//2, (png_h - rendered_png.height)//2) final_img.paste(rendered_png, offset) final_img.save("scaled_reference.png")
方案2:修改SVG属性适配目标尺寸
直接调整SVG的width、height和viewBox属性,让其原生匹配目标PNG尺寸,再渲染:
import xml.etree.ElementTree as ET from svglib.svglib import svg2rlg from reportlab.graphics import renderPM from PIL import Image # 获取目标PNG尺寸 png_img = Image.open("comparison.png") target_w, target_h = png_img.size # 修改SVG属性 ET.register_namespace("", "http://www.w3.org/2000/svg") tree = ET.parse("reference.svg") root = tree.getroot() root.set("width", f"{target_w}px") root.set("height", f"{target_h}px") # 适配viewBox:已有则修改宽高,无则直接设置 if "viewBox" in root.attrib: vb_x, vb_y, _, _ = map(float, root.get("viewBox").split()) root.set("viewBox", f"{vb_x} {vb_y} {target_w} {target_h}") else: root.set("viewBox", f"0 0 {target_w} {target_h}") tree.write("adjusted_reference.svg") # 渲染修改后的SVG drawing = svg2rlg("adjusted_reference.svg") renderPM.drawToFile(drawing, "matched_reference.png", fmt="PNG")
方案3:换用CairoSVG直接指定输出尺寸
CairoSVG支持直接设置输出宽高,自动保持SVG比例并填充空白区域,无需手动计算:
import cairosvg from PIL import Image png_img = Image.open("comparison.png") target_w, target_h = png_img.size cairosvg.svg2png( url="reference.svg", write_to="matched_reference.png", output_width=target_w, output_height=target_h )
内容的提问来源于stack exchange,提问作者twol
相关产品推荐
相关产品推荐

