Files
reTraining/scripts/export_diagram_png.py

77 lines
2.3 KiB
Python

"""
Deterministic SVG to High-Resolution PNG Export Pipeline
Renders docs/diagram-alur.svg to docs/diagram-alur.png at 3840x2160 (4K UHD)
using Playwright Chromium with device_scale_factor=2.0.
Usage:
uv run python scripts/export_diagram_png.py
"""
import asyncio
from pathlib import Path
from playwright.async_api import async_playwright
from PIL import Image
async def export_svg_to_png(
svg_path: Path,
png_path: Path,
width: int = 1920,
height: int = 1080,
scale: float = 2.0
) -> None:
if not svg_path.exists():
raise FileNotFoundError(f"SVG file not found: {svg_path}")
svg_content = svg_path.read_text(encoding="utf-8")
async with async_playwright() as p:
browser = await p.chromium.launch()
page = await browser.new_page(
viewport={"width": width, "height": height},
device_scale_factor=scale
)
html_wrapper = f"""<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<style>
* {{ box-sizing: border-box; margin: 0; padding: 0; }}
html, body {{ width: 100vw; height: 100vh; overflow: hidden; background-color: #080c14; }}
svg {{ display: block; width: 100%; height: 100%; }}
</style>
</head>
<body>{svg_content}</body>
</html>"""
await page.set_content(html_wrapper)
# Ensure all drop shadows and fonts settle
await page.wait_for_timeout(350)
png_bytes = await page.screenshot(type="png")
await browser.close()
png_path.parent.mkdir(parents=True, exist_ok=True)
png_path.write_bytes(png_bytes)
# Verification
with Image.open(png_path) as img:
w, h = img.size
mode = img.mode
file_size_kb = len(png_bytes) / 1024
print(f"Exported PNG successfully: {png_path}")
print(f"Dimensions: {w}x{h} px | Mode: {mode} | Size: {file_size_kb:.1f} KB")
assert w >= 2400 and h >= 1350, f"Resolution check failed: {w}x{h}"
assert w == 3840 and h == 2160, f"Expected 3840x2160, got {w}x{h}"
def main():
root = Path(__file__).resolve().parent.parent
svg_file = root / "docs" / "diagram-alur.svg"
png_file = root / "docs" / "diagram-alur.png"
print(f"Rendering SVG from: {svg_file}")
print(f"Target PNG: {png_file}")
asyncio.run(export_svg_to_png(svg_file, png_file, scale=2.0))
if __name__ == "__main__":
main()