""" Export loading screen animation as a list of unique, ordered frames. Outputs: - frames/frame_XXXX.png — one PNG per unique frame - frames/frames.npy — numpy array of shape (n_unique, H, W), dtype bool Run with: uv run export_loading_frames.py [--out-dir frames] """ import argparse import os import sys import numpy as np from frontend.views.loading import LoadingView def render_all_frames(view: LoadingView) -> list: """Render every animation frame and return as list of PIL Images.""" frames = [] while True: im, done = view.get_frame() frames.append(im) if done: break return frames def deduplicate(frames: list) -> list: """Keep only frames that differ from the previous one.""" unique = [frames[0]] prev = frames[0].tobytes() for im in frames[1:]: b = im.tobytes() if b != prev: unique.append(im) prev = b return unique def main(): parser = argparse.ArgumentParser(description="Export loading screen frames.") parser.add_argument("--out-dir", default="frames", help="Output directory") args = parser.parse_args() size = (168, 144) center = (168 // 2, 144 // 2) view = LoadingView(size, center) all_frames = render_all_frames(view) unique_frames = deduplicate(all_frames) print(f"Total frames rendered : {len(all_frames)}") print(f"Unique frames exported: {len(unique_frames)}") os.makedirs(args.out_dir, exist_ok=True) # Save individual PNGs for i, im in enumerate(unique_frames): im.save(os.path.join(args.out_dir, f"frame_{i:04d}.png")) # Save as numpy array (bool, shape: n_frames x H x W) arr = np.stack([np.array(im) for im in unique_frames]) # shape (N, H, W) npy_path = os.path.join(args.out_dir, "frames.npy") np.save(npy_path, arr) print(f"Saved PNGs and {npy_path} ({arr.shape}, {arr.dtype})") if __name__ == "__main__": main()