layoutenv / dataset /dataset.py
Ryz3n758's picture
Upload folder using huggingface_hub
fb9f8c7 verified
Raw
History Blame Contribute Delete
5.47 kB
import argparse
import json
import os
import sys
from pathlib import Path
from datasets import load_dataset
from PIL import Image
from tqdm import tqdm
def normalize_bbox(bbox, width, height):
x1, y1, x2, y2 = bbox
return [
x1 / width,
y1 / height,
x2 / width,
y2 / height,
]
def _maybe_resize(img: Image.Image, image_size: int | None) -> Image.Image:
if image_size is None:
return img
im = img.copy()
im.thumbnail((image_size, image_size), Image.Resampling.LANCZOS)
return im
def _save_image(img: Image.Image, path: Path, image_size: int | None) -> None:
path.parent.mkdir(parents=True, exist_ok=True)
out = _maybe_resize(img, image_size)
# Preserve alpha when present; JPEG would drop it.
out.save(path, optimize=True)
def _media_path_for_json(saved: Path, output_json: Path) -> str:
"""Path of saved file relative to the JSON file's directory."""
out_dir = output_json.parent.resolve()
saved_r = saved.resolve()
return Path(os.path.relpath(saved_r, out_dir)).as_posix()
def parse_args(argv: list[str] | None = None) -> argparse.Namespace:
here = Path(__file__).resolve().parent
p = argparse.ArgumentParser(description=__doc__)
p.add_argument(
"--output",
type=Path,
default=here / "genposter_subset.json",
help="Output JSON path",
)
p.add_argument(
"--images-dir",
type=Path,
default=here / "images",
help="Directory for downloaded images (when --download-images)",
)
p.add_argument(
"--max-samples",
type=int,
default=5000,
help="Max training rows to scan from the streaming dataset",
)
p.add_argument(
"--download-images",
action="store_true",
help="Download background and per-layer images (large disk use vs metadata-only)",
)
p.add_argument(
"--image-size",
type=int,
default=None,
metavar="N",
help="If set, fit each image inside N×N (aspect preserved; PIL thumbnail)",
)
return p.parse_args(argv)
def main(argv: list[str] | None = None) -> int:
args = parse_args(argv)
dataset = load_dataset(
"creative-graphic-design/GenPoster100K", split="train", streaming=True
)
processed_data = []
sid: str | int | None = None
try:
for i, sample in enumerate(tqdm(dataset, total=args.max_samples)):
if i >= args.max_samples:
break
sid = sample.get("id")
try:
layer_columns = sample["layers"]
bboxes = layer_columns["bbox"]
n = len(bboxes)
if n == 0:
continue
width, height = layer_columns["psd_size"][0]
labels = layer_columns.get("label", [""] * n)
texts = layer_columns.get("text", [""] * n)
font_sizes = layer_columns.get("font_size", [0] * n)
layer_images = layer_columns.get("layer_image") if args.download_images else None
elements = []
for j in range(n):
bbox = bboxes[j]
if bbox is None:
continue
el = {
"type": labels[j] if j < len(labels) else "unknown",
"text": texts[j] if j < len(texts) else "",
"bbox": normalize_bbox(bbox, width, height),
"font_size": float(font_sizes[j])
if j < len(font_sizes) and font_sizes[j] is not None
else 0,
}
if args.download_images and layer_images is not None:
if j < len(layer_images) and layer_images[j] is not None:
layer_name = f"{sid}_layer_{len(elements)}.png"
layer_path = args.images_dir / layer_name
_save_image(layer_images[j], layer_path, args.image_size)
el["layer_image_path"] = _media_path_for_json(
layer_path, args.output
)
elements.append(el)
if len(elements) == 0:
continue
row = {
"id": sid,
"canvas_size": [width, height],
"elements": elements,
}
if args.download_images:
bg = sample.get("background_image")
if bg is not None:
bg_name = f"{sid}_bg.png"
bg_path = args.images_dir / bg_name
_save_image(bg, bg_path, args.image_size)
row["image_path"] = _media_path_for_json(bg_path, args.output)
processed_data.append(row)
except Exception:
continue
except KeyboardInterrupt:
print(f"\nInterrupted after {len(processed_data)} samples (last id={sid!r}).", file=sys.stderr)
args.output.parent.mkdir(parents=True, exist_ok=True)
with open(args.output, "w", encoding="utf-8") as f:
json.dump(processed_data, f)
print(f"Saved {len(processed_data)} samples to {args.output}")
return 0
if __name__ == "__main__":
raise SystemExit(main())