#!/usr/bin/env python3 # -*- coding: utf-8 -*- """服务端 PNG 渲染:通过 sharp 将 SVG 转为 PNG。""" import os import subprocess def _script_path(): return os.path.join(os.path.dirname(__file__), "svg_to_png.js") def render_png_from_svg(svg_text, width, height, *, timeout_seconds=20): if not svg_text or not str(svg_text).strip(): raise ValueError("SVG 内容为空") script = _script_path() if not os.path.isfile(script): raise FileNotFoundError(f"未找到 SVG 转 PNG 脚本: {script}") safe_width = max(1, min(4096, int(round(float(width or 0) or 0)))) safe_height = max(1, min(4096, int(round(float(height or 0) or 0)))) cmd = [ "node", script, "--width", str(safe_width), "--height", str(safe_height), ] try: completed = subprocess.run( cmd, input=str(svg_text).encode("utf-8"), stdout=subprocess.PIPE, stderr=subprocess.PIPE, timeout=timeout_seconds, check=False, ) except FileNotFoundError as error: raise RuntimeError("未找到 node,请先安装 Node.js") from error if completed.returncode != 0: stderr = completed.stderr.decode("utf-8", errors="replace").strip() if "Cannot find module 'sharp'" in stderr: raise RuntimeError("缺少 sharp 依赖,请在项目根目录执行: npm install") raise RuntimeError(stderr or f"PNG 渲染失败,退出码: {completed.returncode}") png_bytes = completed.stdout if not png_bytes: raise RuntimeError("PNG 渲染失败,返回空内容") return png_bytes