AlterProgramming's picture
Initial venture-studio deploy: pixel_cursor + studio + app.py
1e3ce4c verified
Raw
History Blame Contribute Delete
2.16 kB
"""I/O helpers: FrameStack <-> .npz round-trip, ndarray -> video file.
GIF export uses Pillow (always available). MP4/WebM/MKV export uses imageio
when installed (optional extra: `pip install 'venture-studio[video]'`); without
it, those extensions raise a clean ImportError with the install instruction.
"""
from __future__ import annotations
from pathlib import Path
import numpy as np
from PIL import Image as PILImage
from pixel_cursor import FrameStack
from pixel_cursor.artifact import _new_framestack
def save_framestack_npz(stack: FrameStack, path: Path | str) -> Path:
out = Path(path)
np.savez_compressed(
str(out),
frames=stack.frames,
fps=np.array(stack.fps, dtype=np.int32),
name=np.array(stack.name, dtype="U256"),
)
return out
def load_framestack_npz(path: Path | str) -> FrameStack:
data = np.load(str(path), allow_pickle=False)
name = str(data["name"]) if "name" in data.files else ""
return _new_framestack(data["frames"], fps=int(data["fps"]), name=name)
def export_video(stack: FrameStack, out_path: Path | str) -> Path:
out = Path(out_path)
ext = out.suffix.lower()
if ext == ".gif":
return _export_gif(stack, out)
if ext in (".mp4", ".webm", ".mkv", ".avi"):
return _export_imageio(stack, out)
raise ValueError(
f"Unsupported export extension {ext!r}; supported: .gif .mp4 .webm .mkv .avi"
)
def _export_gif(stack: FrameStack, out: Path) -> Path:
frames = [PILImage.fromarray(stack.frames[i]) for i in range(stack.num_frames)]
duration_ms = max(1, 1000 // max(1, stack.fps))
frames[0].save(
out, save_all=True, append_images=frames[1:], duration=duration_ms, loop=0
)
return out
def _export_imageio(stack: FrameStack, out: Path) -> Path:
try:
import imageio.v3 as iio
except ImportError as e:
raise ImportError(
f"Exporting to {out.suffix} requires imageio. Install with: "
f"pip install 'venture-studio[video]' (or: pip install imageio imageio-ffmpeg)"
) from e
iio.imwrite(str(out), stack.frames, fps=stack.fps)
return out