MultiAlphaComposite

This commit is contained in:
nofunstudio
2025-06-25 14:08:45 -06:00
parent ef5b94c0d5
commit 1e5ce8538a
2 changed files with 74 additions and 2 deletions
+5 -2
View File
@@ -9,6 +9,7 @@ from .ksampler_fun import KSampler
from .fal_recraft_upscale import FalAPI_recraft_upscale
from .fal_kling_video import FalAPI_kling_video
from .string_lower import StringLower
from .multi_alpha_composite import MultiAlphaComposite
WEB_DIRECTORY = "./js"
NODE_CLASS_MAPPINGS = {
@@ -21,7 +22,8 @@ NODE_CLASS_MAPPINGS = {
"Fun KSampler": KSampler,
"FalAPI_recraft_upscale": FalAPI_recraft_upscale,
"FalAPI_kling_video": FalAPI_kling_video,
"StringLower": StringLower
"StringLower": StringLower,
"MultiAlphaComposite": MultiAlphaComposite
}
NODE_DISPLAY_NAME_MAPPINGS = {
"LayeredInfiniteZoom": "Layered Infinite Zoom",
@@ -33,7 +35,8 @@ NODE_DISPLAY_NAME_MAPPINGS = {
"Fun KSampler": "Fun KSampler",
"FalAPI_recraft_upscale": "Fal API Recraft Upscale",
"FalAPI_kling_video": "Fal API Kling Video",
"StringLower": "String to Lowercase"
"StringLower": "String to Lowercase",
"MultiAlphaComposite": "Multi Alpha Composite"
}
__all__ = [
+69
View File
@@ -0,0 +1,69 @@
from PIL import Image
import numpy as np
import torch
def tensor_to_pil(tensor):
"""Convert ComfyUI tensor to PIL Image"""
# ComfyUI tensors are typically in format [batch, height, width, channels]
if len(tensor.shape) == 4:
tensor = tensor.squeeze(0) # Remove batch dimension
# Convert from tensor to numpy array and scale to 0-255
np_image = (tensor.cpu().numpy() * 255).astype(np.uint8)
return Image.fromarray(np_image, 'RGB')
def pil_to_tensor(pil_image):
"""Convert PIL Image to ComfyUI tensor"""
np_image = np.array(pil_image).astype(np.float32) / 255.0
tensor = torch.from_numpy(np_image)
return tensor.unsqueeze(0) # Add batch dimension
class MultiAlphaComposite:
CATEGORY = "Image/Composite"
@classmethod
def INPUT_TYPES(s):
return {
"required": {
"num_images": ("INT", {"default": 2, "min": 2, "max": 8, "step": 1}),
"image1": ("IMAGE",),
"image2": ("IMAGE",),
},
"optional": {
"image3": ("IMAGE",),
"image4": ("IMAGE",),
"image5": ("IMAGE",),
"image6": ("IMAGE",),
"image7": ("IMAGE",),
"image8": ("IMAGE",),
}
}
RETURN_TYPES = ("IMAGE",)
FUNCTION = "composite"
def composite(self, num_images, image1, image2, image3=None, image4=None, image5=None, image6=None, image7=None, image8=None):
# Collect all provided images up to num_images
images = [image1, image2, image3, image4, image5, image6, image7, image8]
valid_images = [img for img in images[:num_images] if img is not None]
if len(valid_images) < 2:
raise ValueError("At least 2 images are required for compositing")
# Convert ComfyUI tensors to PIL Images
pil_images = [tensor_to_pil(img) for img in valid_images]
# Convert to RGBA for alpha compositing
layers = [img.convert("RGBA") for img in pil_images]
# Composite layers
base = layers[0]
for layer in layers[1:]:
# Resize layer to match base if needed
if layer.size != base.size:
layer = layer.resize(base.size, Image.LANCZOS)
base = Image.alpha_composite(base, layer)
# Convert back to ComfyUI tensor format
result_tensor = pil_to_tensor(base.convert("RGB"))
return (result_tensor,)