Add image thumbnail previews for node-triggered snapshots

When SaveSnapshot receives an image tensor, extract a 200x150 JPEG
thumbnail (base64) and include it in the snapshot record. Sidebar shows
a small preview, tooltip displays the generated image instead of SVG,
and the preview modal shows the image above the graph.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-02-27 12:42:51 +01:00
parent e29e7dfad1
commit f9bdc75a2a
2 changed files with 75 additions and 15 deletions

View File

@@ -1,3 +1,6 @@
import base64
import io
from server import PromptServer
@@ -9,6 +12,30 @@ class _AnyType(str):
ANY_TYPE = _AnyType("*")
def _make_thumbnail(value):
"""Convert an image tensor to a base64 JPEG thumbnail, or return None."""
try:
import torch
if not isinstance(value, torch.Tensor):
return None
if value.ndim != 4 or value.shape[3] not in (3, 4):
return None
from PIL import Image
frame = value[0] # first frame only
if frame.shape[2] == 4:
frame = frame[:, :, :3] # drop alpha
arr = frame.clamp(0, 1).mul(255).byte().cpu().numpy()
img = Image.fromarray(arr, mode="RGB")
img.thumbnail((200, 150), Image.LANCZOS)
buf = io.BytesIO()
img.save(buf, format="JPEG", quality=75)
return base64.b64encode(buf.getvalue()).decode("ascii")
except Exception:
return None
class SaveSnapshot:
CATEGORY = "Snapshot Manager"
FUNCTION = "execute"
@@ -33,7 +60,11 @@ class SaveSnapshot:
return float("NaN")
def execute(self, value, label):
payload = {"label": label}
thumbnail = _make_thumbnail(value)
if thumbnail is not None:
payload["thumbnail"] = thumbnail
PromptServer.instance.send_sync(
"snapshot-manager-capture", {"label": label}
"snapshot-manager-capture", payload
)
return (value,)