#!/usr/bin/env python3 """ SVG to PNG Renderer ========== 将 SVG 文件渲染为 PNG 图片。 依赖: pip install cairosvg Pillow 用法: # 基本用法(自动读取 SVG 尺寸) python svg-to-png.py input.svg output.png # 指定输出宽度(高度等比缩放) python svg-to-png.py input.svg output.png --width 1920 # 指定输出高度(宽度等比缩放) python svg-to-png.py input.svg output.png --height 1080 # 指定缩放因子(基于 SVG 原始尺寸放大 / 缩小) python svg-to-png.py input.svg output.png --scale 2 # 批量转换目录下的所有 SVG python svg-to-png.py ./svg-dir/ ./png-dir/ --batch # 作为模块导入 from svg_to_png import convert_svg_to_png convert_svg_to_png("input.svg", "output.png", scale=2) 路径: video-ai-system/tools/svg-to-png.py """ import argparse import os import sys from pathlib import Path try: import cairosvg from PIL import Image except ImportError as e: print(f"[ERROR] 缺少依赖:{e}") print("请先安装:pip install cairosvg Pillow") sys.exit(1) def convert_svg_to_png( svg_path: str, png_path: str, width: int = None, height: int = None, scale: float = None, background: str = "white", ) -> bool: """ 将单个 SVG 文件转换为 PNG。 :param svg_path: 输入 SVG 文件路径 :param png_path: 输出 PNG 文件路径 :param width: 输出宽度(px),为 None 时保留 SVG 原始宽度 :param height: 输出高度(px),为 None 时保留 SVG 原始高度 :param scale: 缩放因子,基于 SVG 原始尺寸等比缩放 :param background: 背景色,默认白色;设为 None 保留透明 :return: 是否转换成功 """ if not os.path.isfile(svg_path): print(f"[ERROR] SVG 文件不存在:{svg_path}") return False # 确保输出目录存在 os.makedirs(os.path.dirname(os.path.abspath(png_path)), exist_ok=True) try: # 构造 cairosvg 参数 kwargs = { "url": svg_path, "write_to": png_path, } if background: kwargs["background_color"] = background if scale is not None: kwargs["scale"] = scale else: if width is not None: kwargs["output_width"] = width if height is not None: kwargs["output_height"] = height cairosvg.svg2png(**kwargs) # 验证输出文件 if os.path.isfile(png_path): file_size = os.path.getsize(png_path) print(f"[OK] {svg_path} → {png_path} ({file_size // 1024} KB)") return True else: print(f"[ERROR] 输出文件未生成:{png_path}") return False except Exception as e: print(f"[ERROR] 转换失败 {svg_path}:{e}") return False def batch_convert( svg_dir: str, png_dir: str, width: int = None, height: int = None, scale: float = None, ) -> tuple: """ 批量转换目录下的所有 SVG 文件。 :param svg_dir: 输入目录(包含 SVG 文件) :param png_dir: 输出目录 :return: (成功数, 总数) """ if not os.path.isdir(svg_dir): print(f"[ERROR] 输入目录不存在:{svg_dir}") return 0, 0 os.makedirs(png_dir, exist_ok=True) svg_files = sorted(Path(svg_dir).glob("*.svg")) if not svg_files: print(f"[WARN] 目录中没有找到 SVG 文件:{svg_dir}") return 0, 0 print(f"[INFO] 找到 {len(svg_files)} 个 SVG 文件,开始批量转换...") success = 0 total = len(svg_files) for svg_file in svg_files: png_file = os.path.join(png_dir, svg_file.stem + ".png") if convert_svg_to_png( str(svg_file), png_file, width=width, height=height, scale=scale ): success += 1 print(f"\n[INFO] 批量转换完成:{success}/{total} 成功") return success, total def main(): parser = argparse.ArgumentParser( description="SVG to PNG 渲染工具(基于 CairoSVG)", formatter_class=argparse.RawDescriptionHelpFormatter, epilog=""" 示例: python svg-to-png.py input.svg output.png python svg-to-png.py input.svg output.png --width 1920 python svg-to-png.py ./svg/ ./png/ --batch --scale 2 """ ) parser.add_argument("input", help="输入 SVG 文件或目录") parser.add_argument("output", help="输出 PNG 文件或目录") parser.add_argument("--width", type=int, default=None, help="输出宽度(px)") parser.add_argument("--height", type=int, default=None, help="输出高度(px)") parser.add_argument("--scale", type=float, default=None, help="缩放因子") parser.add_argument("--batch", action="store_true", help="批量转换模式") parser.add_argument("--background", default="white", help="背景色(默认 white,设为 'none' 保留透明)") args = parser.parse_args() if args.batch or os.path.isdir(args.input): # 批量模式 success, total = batch_convert( args.input, args.output, width=args.width, height=args.height, scale=args.scale ) sys.exit(0 if success == total else 1) else: # 单文件模式 bg = None if args.background.lower() == "none" else args.background ok = convert_svg_to_png( args.input, args.output, width=args.width, height=args.height, scale=args.scale, background=bg ) sys.exit(0 if ok else 1) if __name__ == "__main__": main()