from PIL import Image, ImageOps import numpy as np import torch, base64, io def b64_to_img_and_mask(image_base64): imageData = base64.b64decode(image_base64) i = Image.open(io.BytesIO(imageData)) if hasattr(i, 'is_animated') and i.is_animated: images = [] for frame in range(i.n_frames): i.seek(frame) images.append(i.convert("RGB")) i.seek(0) image = np.array(images).astype(np.float32) / 255.0 image = torch.from_numpy(image) else: i = ImageOps.exif_transpose(i) image = i.convert("RGB") image = np.array(image).astype(np.float32) / 255.0 image = torch.from_numpy(image)[None,] if 'A' in i.getbands(): mask = np.array(i.getchannel('A')).astype(np.float32) / 255.0 mask = 1. - torch.from_numpy(mask) else: mask = torch.zeros((64,64), dtype=torch.float32, device="cpu") return (image, mask.unsqueeze(0)) class SwarmLoadImageB64: @classmethod def INPUT_TYPES(s): return { "required": { "image_base64": ("STRING", {"multiline": True}) } } CATEGORY = "SwarmUI/images" RETURN_TYPES = ("IMAGE", "MASK") FUNCTION = "load_image_b64" DESCRIPTION = "Loads an image from a base64 string. Works like a regular LoadImage node, but with input format designed to be easier to use through automated calls, including SwarmUI with custom workflows." def load_image_b64(self, image_base64): return b64_to_img_and_mask(image_base64) NODE_CLASS_MAPPINGS = { "SwarmLoadImageB64": SwarmLoadImageB64, }