Files
CompanionGuard-RL/tools/html_to_ppt_make.py

69 lines
2.0 KiB
Python
Raw Permalink Normal View History

import json
import sys
from pathlib import Path
from PIL import Image, ImageOps
from pptx import Presentation
from pptx.util import Inches
def main() -> None:
if len(sys.argv) != 3:
raise SystemExit("Usage: python html_to_ppt_make.py <image-dir> <output-pptx>")
image_dir = Path(sys.argv[1])
output_pptx = Path(sys.argv[2])
output_pptx.parent.mkdir(parents=True, exist_ok=True)
labels_path = image_dir / "slides.json"
labels = {}
if labels_path.exists():
labels = {item["index"]: item["label"] for item in json.loads(labels_path.read_text(encoding="utf-8"))}
image_paths = sorted(image_dir.glob("slide_*.png"))
if not image_paths:
raise SystemExit(f"No slide PNGs found in {image_dir}")
prs = Presentation()
prs.slide_width = Inches(13.333333)
prs.slide_height = Inches(7.5)
blank_layout = prs.slide_layouts[6]
for image_path in image_paths:
slide_num = int(image_path.stem.split("_")[-1])
slide = prs.slides.add_slide(blank_layout)
picture = slide.shapes.add_picture(
str(image_path),
0,
0,
width=prs.slide_width,
height=prs.slide_height,
)
picture.name = labels.get(slide_num, image_path.stem)
prs.save(output_pptx)
montage_path = output_pptx.with_suffix(".preview.png")
thumbs = []
for image_path in image_paths:
img = Image.open(image_path).convert("RGB")
img.thumbnail((384, 216), Image.Resampling.LANCZOS)
thumbs.append(ImageOps.expand(img, border=2, fill=(30, 30, 30)))
cols = 5
rows = (len(thumbs) + cols - 1) // cols
montage = Image.new("RGB", (cols * 388, rows * 220), (12, 15, 24))
for idx, thumb in enumerate(thumbs):
x = (idx % cols) * 388
y = (idx // cols) * 220
montage.paste(thumb, (x, y))
montage.save(montage_path)
print(f"pptx={output_pptx}")
print(f"preview={montage_path}")
print(f"slides={len(image_paths)}")
if __name__ == "__main__":
main()