feat(scripts): Potrace floor-plan vectorization spike (#299) #1663

Merged
lekss361 merged 2 commits from feat/plan-vectorization-spike-299 into main 2026-06-17 17:12:49 +00:00
Showing only changes of commit 838e8a9639 - Show all commits

View file

@ -93,9 +93,7 @@ def _require_binary(name: str) -> str:
path = shutil.which(name)
if path is None:
logger.error("required binary %r not found on PATH", name)
raise SystemExit(
f"{name!r} not found — install it (e.g. `brew install {name}`) and retry"
)
raise SystemExit(f"{name!r} not found — install it (e.g. `brew install {name}`) and retry")
return path
@ -145,9 +143,13 @@ def svg_to_png(rsvg_bin: str, svg_path: Path, png_path: Path, *, width: int) ->
try:
subprocess.run(
[
rsvg_bin, "-w", str(width),
rsvg_bin,
"-w",
str(width),
"--background-color=white",
"-o", str(png_path), str(svg_path),
"-o",
str(png_path),
str(svg_path),
],
check=True,
capture_output=True,
@ -216,8 +218,10 @@ def summarise(results: list[VectorizeResult]) -> None:
print(f"max ratio : {max(ratios):.2f}x")
total_raster = sum(r.raster_bytes for r in results)
total_svg = sum(r.svg_bytes for r in results)
print(f"aggregate : {total_raster}B raster -> {total_svg}B svg "
f"({total_raster / total_svg:.2f}x overall)")
agg_ratio = total_raster / total_svg if total_svg else float("inf")
print(
f"aggregate : {total_raster}B raster -> {total_svg}B svg " f"({agg_ratio:.2f}x overall)"
)
def build_parser() -> argparse.ArgumentParser:
@ -225,27 +229,37 @@ def build_parser() -> argparse.ArgumentParser:
description="Spike: contour-vectorize floor-plan rasters (PNG/JPG → SVG) via Potrace.",
)
parser.add_argument(
"--in-dir", type=Path, required=True,
"--in-dir",
type=Path,
required=True,
help="folder containing input rasters (PNG/JPG/...)",
)
parser.add_argument(
"--out-dir", type=Path, required=True,
"--out-dir",
type=Path,
required=True,
help="folder for output .pbm/.svg (and .rendered.png with --render-back)",
)
parser.add_argument(
"--threshold", type=int, default=128,
"--threshold",
type=int,
default=128,
help="grayscale ink/paper cutoff 0-255 (default 128)",
)
parser.add_argument(
"--invert", action="store_true",
"--invert",
action="store_true",
help="treat light strokes on a dark field as ink",
)
parser.add_argument(
"--render-back", action="store_true",
"--render-back",
action="store_true",
help="rasterise each SVG back to PNG via rsvg-convert for visual QA",
)
parser.add_argument(
"--render-width", type=int, default=900,
"--render-width",
type=int,
default=900,
help="width in px for --render-back output (default 900)",
)
return parser