铸渊 ICE-GL-ZY001 LL-172-20260707 冰朔委托: 新建第 5 子仓, 给苍耳(人类主控) + 鉴影(人格体) 专用 原 guanghulab/video-ai-system/ 东西太多(225 文件) · 找不到 · 乱 迁移: ⊢ 16 个核心 .hdlp (VA-GATE / VA-LIGHTHOUSE / VA-BROADCAST / VA-SYSTEM-STATUS 等) ⊢ 17 个子目录 (agents/engines/protocols/tasks/tools/assets/knowledge/memory/docs/config/brain/director-brain/experience/feedback/issues/plans/reference-analysis) 排除: ⊢ outputs/ (视频产物) ⊢ test-input/ test-output/ (测试) ⊢ data/ (临时数据) ⊢ preview-001/002 (旧产片) ⊢ 旧分镜/旧提示词/旧导演编码 后续: ⊢ 老仓 guanghulab/video-ai-system/ 改写为已迁出占位 ⊢ 苍耳+鉴影 写新东西进本仓 ⊢ GLOBAL-SEARCH 加 cang-ying 仓库 铸渊 ICE-GL-ZY001 · 2026-07-07 D167 冰朔 ICE-GL∞ 主权
190 lines
5.5 KiB
Python
190 lines
5.5 KiB
Python
#!/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()
|