| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354 |
- from __future__ import annotations
- import json
- import sys
- from pathlib import Path
- from PIL import Image, ImageDraw, ImageFont
- REVIEW_DIR = Path(sys.argv[1] if len(sys.argv) > 1 else "artifacts/music-template-extraction/review")
- OUTPUT_DIR = Path(sys.argv[2] if len(sys.argv) > 2 else "artifacts/music-template-extraction/contact-sheets")
- ROWS_PER_SHEET = 6
- THUMBNAIL = (300, 169)
- MARGIN = 18
- LABEL_HEIGHT = 54
- def font(size: int, bold: bool = False):
- path = Path(r"C:\Windows\Fonts\msyhbd.ttc" if bold else r"C:\Windows\Fonts\msyh.ttc")
- try:
- return ImageFont.truetype(str(path), size)
- except OSError:
- return ImageFont.load_default()
- def main() -> None:
- manifest = json.loads((REVIEW_DIR / "manifest.json").read_text(encoding="utf-8"))
- items = manifest["items"]
- OUTPUT_DIR.mkdir(parents=True, exist_ok=True)
- width = MARGIN * 6 + THUMBNAIL[0] * 5
- row_height = THUMBNAIL[1] + LABEL_HEIGHT + MARGIN
- for sheet_index, start in enumerate(range(0, len(items), ROWS_PER_SHEET), start=1):
- page_items = items[start:start + ROWS_PER_SHEET]
- canvas = Image.new("RGB", (width, row_height * len(page_items) + MARGIN), "#EEF1F5")
- draw = ImageDraw.Draw(canvas)
- for row, item in enumerate(page_items):
- top = MARGIN + row * row_height
- label = f"{item['id']} [{item['scene']}] {item['name']}"
- draw.text((MARGIN, top), label[:75], font=font(22, True), fill="#202631")
- for column, sample in enumerate(item["samples"][:5]):
- source = REVIEW_DIR / item["id"] / sample
- with Image.open(source) as raw:
- image = raw.convert("RGB")
- image.thumbnail(THUMBNAIL, Image.Resampling.LANCZOS)
- left = MARGIN + column * (THUMBNAIL[0] + MARGIN)
- image_top = top + LABEL_HEIGHT
- canvas.paste(image, (left, image_top))
- draw.rectangle((left, image_top, left + THUMBNAIL[0], image_top + THUMBNAIL[1]), outline="#B7C0CD", width=2)
- canvas.save(OUTPUT_DIR / f"sheet-{sheet_index:02d}.jpg", quality=90, optimize=True)
- print(json.dumps({"sheets": (len(items) + ROWS_PER_SHEET - 1) // ROWS_PER_SHEET, "items": len(items)}, ensure_ascii=False))
- if __name__ == "__main__":
- main()
|