"""Extract embedded images from a GLB file (stdlib only). Usage: python3 extract_glb_textures.py """ import json import struct import sys from pathlib import Path def extract(glb_path: Path, out_dir: Path) -> None: out_dir.mkdir(parents=True, exist_ok=True) with open(glb_path, "rb") as f: magic, version, total = struct.unpack("<4sII", f.read(12)) if magic != b"glTF": raise SystemExit(f"not a GLB: {glb_path}") json_len, json_type = struct.unpack(" image[{src}]" + (f" = {image_paths[src].name}" if src is not None and image_paths[src] else "")) print("\n[materials]") for i, mat in enumerate(materials): name = mat.get("name", f"mat_{i}") pbr = mat.get("pbrMetallicRoughness", {}) bct = pbr.get("baseColorTexture", {}).get("index") mrt = pbr.get("metallicRoughnessTexture", {}).get("index") nrm = mat.get("normalTexture", {}).get("index") emi = mat.get("emissiveTexture", {}).get("index") occ = mat.get("occlusionTexture", {}).get("index") print(f" material[{i}] {name}:") print(f" baseColor -> texture[{bct}]" if bct is not None else " baseColor -> (none)") print(f" metalRough -> texture[{mrt}]" if mrt is not None else " metalRough -> (none)") print(f" normal -> texture[{nrm}]" if nrm is not None else " normal -> (none)") print(f" emissive -> texture[{emi}]" if emi is not None else " emissive -> (none)") print(f" occlusion -> texture[{occ}]" if occ is not None else " occlusion -> (none)") if __name__ == "__main__": if len(sys.argv) != 3: print(__doc__) sys.exit(1) extract(Path(sys.argv[1]).expanduser(), Path(sys.argv[2]).expanduser())