Files

244 lines
16 KiB
Python

# SPDX-License-Identifier: Apache-2.0
# Copyright 2025-2026 Raykosan (RaykoStudio)
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import torch
import math
class RS_Image_MultiLatent:
@classmethod
def INPUT_TYPES(cls):
return {
"required": {
"vae": ("VAE",),
"size_mode": (["Preset", "Custom", "Megapixels"],),
"active_preset": (["Standard", "Qwen", "Krea2"], {"default": "Standard"}),
"preset_standard": (
[
"Square - 512x512 (1:1)", "Square - 640x640 (1:1)", "Square - 768x768 (1:1)",
"Square - 1024x1024 (1:1)", "Square - 1280x1280 (1:1)", "Square - 1536x1536 (1:1)",
"Square - 1920x1920 (1:1)",
"Portrait - 480x640 (3:4)", "Portrait - 512x768 (2:3)", "Portrait - 768x1024 (3:4)",
"Portrait - 864x1152 (3:4)", "Portrait - 960x1280 (3:4)", "Portrait - 768x1152 (2:3)",
"Portrait - 896x1344 (2:3)", "Portrait - 768x1344 (9:16)", "Portrait - 832x1152 (3:4)",
"Portrait - 832x1216 (13:19)", "Portrait - 896x1088 (14:17)", "Portrait - 896x1152 (7:9)",
"Portrait - 960x1024 (15:16)", "Portrait - 960x1088 (15:17)", "Portrait - 1024x1280 (4:5)",
"Portrait - 1280x1536 (5:6)", "Portrait - 1344x1728 (7:9)", "Portrait - 1440x1920 (3:4)",
"Portrait - 1024x1536 (2:3)", "Portrait - 1088x1856 (~6:10)", "Portrait - 1280x1920 (2:3)",
"Portrait - 1080x1920 (9:16)", "Portrait - 816x1920 (9:21)",
"Landscape - 640x480 (4:3)", "Landscape - 768x512 (3:2)", "Landscape - 1024x768 (4:3)",
"Landscape - 1280x864 (4:3)", "Landscape - 1280x960 (4:3)", "Landscape - 1152x768 (3:2)",
"Landscape - 1344x896 (3:2)", "Landscape - 1344x768 (7:4)", "Landscape - 1152x832 (9:7)",
"Landscape - 1216x832 (19:13)", "Landscape - 1088x896 (17:14)", "Landscape - 1152x896 (9:7)",
"Landscape - 1024x960 (16:15)", "Landscape - 1088x960 (17:15)", "Landscape - 1280x1024 (5:4)",
"Landscape - 1536x1280 (6:5)", "Landscape - 1728x1344 (9:7)", "Landscape - 1920x1440 (4:3)",
"Landscape - 1536x1024 (3:2)", "Landscape - 1856x1088 (~16:9)", "Landscape - 1920x1280 (3:2)",
"Landscape - 1920x1080 (16:9)", "Landscape - 1920x1024 (15:8)", "Landscape - 1920x816 (21:9)",
],
{"default": "Square - 1024x1024 (1:1)"}
),
"preset_qwen": (
[
"Square - 1008x1008 (1:1)", "Square - 1120x1120 (1:1)", "Square - 1344x1344 (1:1)",
"Square - 1568x1568 (1:1)", "Square - 1792x1792 (1:1)", "Square - 2016x2016 (1:1)",
"Portrait - 896x1120 (4:5)", "Portrait - 896x1344 (2:3)", "Portrait - 1008x1344 (3:4)",
"Portrait - 1008x1792 (9:16)", "Portrait - 1120x1456 (10:13)", "Portrait - 1120x1680 (2:3)",
"Portrait - 1120x1792 (5:8)", "Portrait - 1120x1904 (10:17)", "Portrait - 1120x2016 (5:6)",
"Portrait - 1120x2240 (1:2)", "Portrait - 1232x2016 (11:18)", "Portrait - 1232x2464 (1:2)",
"Portrait - 1344x1792 (3:4)", "Portrait - 1344x2016 (2:3)", "Portrait - 1344x2240 (3:5)",
"Portrait - 1344x2688 (1:2)", "Portrait - 1456x1792 (13:16)", "Portrait - 1456x2912 (1:2)",
"Portrait - 1568x2352 (2:3)", "Portrait - 1680x2016 (5:6)", "Portrait - 1680x2240 (3:4)",
"Portrait - 1792x2240 (4:5)",
"Landscape - 1120x896 (5:4)", "Landscape - 1344x896 (3:2)", "Landscape - 1344x1008 (4:3)",
"Landscape - 1792x1008 (16:9)", "Landscape - 1456x1120 (13:10)", "Landscape - 1680x1120 (3:2)",
"Landscape - 1792x1120 (8:5)", "Landscape - 1904x1120 (17:10)", "Landscape - 2016x1120 (6:5)",
"Landscape - 2240x1120 (2:1)", "Landscape - 2016x1232 (18:11)", "Landscape - 2464x1232 (2:1)",
"Landscape - 1792x1344 (4:3)", "Landscape - 2016x1344 (3:2)", "Landscape - 2240x1344 (5:3)",
"Landscape - 2688x1344 (2:1)", "Landscape - 1792x1456 (16:13)", "Landscape - 2912x1456 (2:1)",
"Landscape - 2352x1568 (3:2)", "Landscape - 2016x1680 (6:5)", "Landscape - 2240x1680 (4:3)",
"Landscape - 2240x1792 (5:4)",
],
{"default": "Square - 1008x1008 (1:1)"}
),
"preset_krea2": (
[
"Square - 512x512 (1:1)", "Square - 640x640 (1:1)", "Square - 768x768 (1:1)",
"Square - 1024x1024 (1:1)", "Square - 1280x1280 (1:1)", "Square - 1536x1536 (1:1)",
"Square - 1920x1920 (1:1)",
"Portrait - 480x640 (3:4)", "Portrait - 512x768 (2:3)", "Portrait - 768x1024 (3:4)",
"Portrait - 864x1152 (3:4)", "Portrait - 960x1280 (3:4)", "Portrait - 768x1152 (2:3)",
"Portrait - 896x1344 (2:3)", "Portrait - 768x1344 (9:16)", "Portrait - 832x1152 (3:4)",
"Portrait - 832x1216 (13:19)", "Portrait - 896x1088 (14:17)", "Portrait - 896x1152 (7:9)",
"Portrait - 960x1024 (15:16)", "Portrait - 960x1088 (15:17)", "Portrait - 1024x1280 (4:5)",
"Portrait - 1280x1536 (5:6)", "Portrait - 1344x1728 (7:9)", "Portrait - 1440x1920 (3:4)",
"Portrait - 1024x1536 (2:3)", "Portrait - 1088x1856 (~6:10)", "Portrait - 1280x1920 (2:3)",
"Portrait - 1080x1920 (9:16)", "Portrait - 816x1920 (9:21)",
"Landscape - 640x480 (4:3)", "Landscape - 768x512 (3:2)", "Landscape - 1024x768 (4:3)",
"Landscape - 1280x864 (4:3)", "Landscape - 1280x960 (4:3)", "Landscape - 1152x768 (3:2)",
"Landscape - 1344x896 (3:2)", "Landscape - 1344x768 (7:4)", "Landscape - 1152x832 (9:7)",
"Landscape - 1216x832 (19:13)", "Landscape - 1088x896 (17:14)", "Landscape - 1152x896 (9:7)",
"Landscape - 1024x960 (16:15)", "Landscape - 1088x960 (17:15)", "Landscape - 1280x1024 (5:4)",
"Landscape - 1536x1280 (6:5)", "Landscape - 1728x1344 (9:7)", "Landscape - 1920x1440 (4:3)",
"Landscape - 1536x1024 (3:2)", "Landscape - 1856x1088 (~16:9)", "Landscape - 1920x1280 (3:2)",
"Landscape - 1920x1080 (16:9)", "Landscape - 1920x1024 (15:8)", "Landscape - 1920x816 (21:9)",
],
{"default": "Square - 1024x1024 (1:1)"}
),
"width": ("INT", {"default": 1024, "min": 8, "max": 4096, "step": 8}),
"height": ("INT", {"default": 1024, "min": 8, "max": 4096, "step": 8}),
"megapixels": ("FLOAT", {"default": 1.0, "min": 0.1, "max": 10.0, "step": 0.1}),
"aspect_ratio": (["1:1", "3:2", "2:3", "4:3", "3:4", "16:9", "9:16", "21:9", "9:21", "4:5", "5:4"],),
"batch_size": ("INT", {"default": 1, "min": 1, "max": 64}),
}
}
RETURN_TYPES = ("LATENT", "INT", "INT")
RETURN_NAMES = ("latent", "width_px", "height_px")
FUNCTION = "generate"
CATEGORY = "🦊 RaykoStudio"
DESCRIPTION = "Universal latent generation node - automatically adapts to any VAE architecture."
def generate(self, vae, size_mode, active_preset, preset_standard, preset_qwen, preset_krea2, width, height, megapixels, aspect_ratio, batch_size):
latent_channels = 4
scale_factor = 8
if hasattr(vae, 'first_stage_config'):
config = vae.first_stage_config
latent_channels = getattr(config, 'latent_channels', 4)
scale_factor = getattr(config, 'scale_factor', 8)
elif hasattr(vae, 'latent_channels'):
latent_channels = vae.latent_channels
scale_factor = getattr(vae, 'scale_factor', 8)
elif hasattr(vae, 'decoder') and hasattr(vae.decoder, 'conv_in'):
try:
if hasattr(vae.decoder, 'config'):
latent_channels = getattr(vae.decoder.config, 'latent_channels', 4)
scale_factor = getattr(vae.decoder.config, 'scale_factor', 8)
except:
pass
if latent_channels <= 0 or latent_channels > 256:
raise ValueError(f"Invalid latent_channels: {latent_channels}")
if scale_factor <= 0 or scale_factor > 64:
raise ValueError(f"Invalid scale_factor: {scale_factor}")
print(f"[RS_Image_MultiLatent] VAE: {latent_channels} channels, {scale_factor}x scale. Active: {active_preset}")
if size_mode == "Preset":
if active_preset == "Standard":
preset = preset_standard
elif active_preset == "Qwen":
preset = preset_qwen
else:
preset = preset_krea2
size_map = {
# Standard & Krea2
"Square - 512x512 (1:1)": (512, 512), "Square - 640x640 (1:1)": (640, 640),
"Square - 768x768 (1:1)": (768, 768), "Square - 1024x1024 (1:1)": (1024, 1024),
"Square - 1280x1280 (1:1)": (1280, 1280), "Square - 1536x1536 (1:1)": (1536, 1536),
"Square - 1920x1920 (1:1)": (1920, 1920),
"Portrait - 480x640 (3:4)": (480, 640), "Portrait - 512x768 (2:3)": (512, 768),
"Portrait - 768x1024 (3:4)": (768, 1024), "Portrait - 864x1152 (3:4)": (864, 1152),
"Portrait - 960x1280 (3:4)": (960, 1280), "Portrait - 768x1152 (2:3)": (768, 1152),
"Portrait - 896x1344 (2:3)": (896, 1344), "Portrait - 768x1344 (9:16)": (768, 1344),
"Portrait - 832x1152 (3:4)": (832, 1152), "Portrait - 832x1216 (13:19)": (832, 1216),
"Portrait - 896x1088 (14:17)": (896, 1088), "Portrait - 896x1152 (7:9)": (896, 1152),
"Portrait - 960x1024 (15:16)": (960, 1024), "Portrait - 960x1088 (15:17)": (960, 1088),
"Portrait - 1024x1280 (4:5)": (1024, 1280), "Portrait - 1280x1536 (5:6)": (1280, 1536),
"Portrait - 1344x1728 (7:9)": (1344, 1728), "Portrait - 1440x1920 (3:4)": (1440, 1920),
"Portrait - 1024x1536 (2:3)": (1024, 1536), "Portrait - 1088x1856 (~6:10)": (1088, 1856),
"Portrait - 1280x1920 (2:3)": (1280, 1920), "Portrait - 1080x1920 (9:16)": (1080, 1920),
"Portrait - 816x1920 (21:9)": (816, 1920),
"Landscape - 640x480 (4:3)": (640, 480), "Landscape - 768x512 (3:2)": (768, 512),
"Landscape - 1024x768 (4:3)": (1024, 768), "Landscape - 1280x864 (4:3)": (1280, 864),
"Landscape - 1280x960 (4:3)": (1280, 960), "Landscape - 1152x768 (3:2)": (1152, 768),
"Landscape - 1344x896 (3:2)": (1344, 896), "Landscape - 1344x768 (7:4)": (1344, 768),
"Landscape - 1152x832 (9:7)": (1152, 832), "Landscape - 1216x832 (19:13)": (1216, 832),
"Landscape - 1088x896 (17:14)": (1088, 896), "Landscape - 1152x896 (9:7)": (1152, 896),
"Landscape - 1024x960 (16:15)": (1024, 960), "Landscape - 1088x960 (17:15)": (1088, 960),
"Landscape - 1280x1024 (5:4)": (1280, 1024), "Landscape - 1536x1280 (6:5)": (1536, 1280),
"Landscape - 1728x1344 (9:7)": (1728, 1344), "Landscape - 1920x1440 (4:3)": (1920, 1440),
"Landscape - 1536x1024 (3:2)": (1536, 1024), "Landscape - 1856x1088 (~16:9)": (1856, 1088),
"Landscape - 1920x1280 (3:2)": (1920, 1280), "Landscape - 1920x1080 (16:9)": (1920, 1080),
"Landscape - 1920x1024 (15:8)": (1920, 1024), "Landscape - 1920x816 (21:9)": (1920, 816),
# Qwen
"Square - 1008x1008 (1:1)": (1008, 1008), "Square - 1120x1120 (1:1)": (1120, 1120),
"Square - 1344x1344 (1:1)": (1344, 1344), "Square - 1568x1568 (1:1)": (1568, 1568),
"Square - 1792x1792 (1:1)": (1792, 1792), "Square - 2016x2016 (1:1)": (2016, 2016),
"Portrait - 896x1120 (4:5)": (896, 1120), "Portrait - 896x1344 (2:3)": (896, 1344),
"Portrait - 1008x1344 (3:4)": (1008, 1344), "Portrait - 1008x1792 (9:16)": (1008, 1792),
"Portrait - 1120x1456 (10:13)": (1120, 1456), "Portrait - 1120x1680 (2:3)": (1120, 1680),
"Portrait - 1120x1792 (5:8)": (1120, 1792), "Portrait - 1120x1904 (10:17)": (1120, 1904),
"Portrait - 1120x2016 (5:6)": (1120, 2016), "Portrait - 1120x2240 (1:2)": (1120, 2240),
"Portrait - 1232x2016 (11:18)": (1232, 2016), "Portrait - 1232x2464 (1:2)": (1232, 2464),
"Portrait - 1344x1792 (3:4)": (1344, 1792), "Portrait - 1344x2016 (2:3)": (1344, 2016),
"Portrait - 1344x2240 (3:5)": (1344, 2240), "Portrait - 1344x2688 (1:2)": (1344, 2688),
"Portrait - 1456x1792 (13:16)": (1456, 1792), "Portrait - 1456x2912 (1:2)": (1456, 2912),
"Portrait - 1568x2352 (2:3)": (1568, 2352), "Portrait - 1680x2016 (5:6)": (1680, 2016),
"Portrait - 1680x2240 (3:4)": (1680, 2240), "Portrait - 1792x2240 (4:5)": (1792, 2240),
"Landscape - 1120x896 (5:4)": (1120, 896), "Landscape - 1344x896 (3:2)": (1344, 896),
"Landscape - 1344x1008 (4:3)": (1344, 1008), "Landscape - 1792x1008 (16:9)": (1792, 1008),
"Landscape - 1456x1120 (13:10)": (1456, 1120), "Landscape - 1680x1120 (3:2)": (1680, 1120),
"Landscape - 1792x1120 (8:5)": (1792, 1120), "Landscape - 1904x1120 (17:10)": (1904, 1120),
"Landscape - 2016x1120 (6:5)": (2016, 1120), "Landscape - 2240x1120 (2:1)": (2240, 1120),
"Landscape - 2016x1232 (18:11)": (2016, 1232), "Landscape - 2464x1232 (2:1)": (2464, 1232),
"Landscape - 1792x1344 (4:3)": (1792, 1344), "Landscape - 2016x1344 (3:2)": (2016, 1344),
"Landscape - 2240x1344 (5:3)": (2240, 1344), "Landscape - 2688x1344 (2:1)": (2688, 1344),
"Landscape - 1792x1456 (16:13)": (1792, 1456), "Landscape - 2912x1456 (2:1)": (2912, 1456),
"Landscape - 2352x1568 (3:2)": (2352, 1568), "Landscape - 2016x1680 (6:5)": (2016, 1680),
"Landscape - 2240x1680 (4:3)": (2240, 1680), "Landscape - 2240x1792 (5:4)": (2240, 1792),
}
width, height = size_map.get(preset, (1024, 1024))
elif size_mode == "Custom":
width = max(8, (width // 8) * 8)
height = max(8, (height // 8) * 8)
elif size_mode == "Megapixels":
w_ratio, h_ratio = map(int, aspect_ratio.split(":"))
target_pixels = megapixels * 1_000_000
x = math.sqrt(target_pixels / (w_ratio * h_ratio))
raw_width = w_ratio * x
raw_height = h_ratio * x
width = round(raw_width / scale_factor) * scale_factor
height = round(raw_height / scale_factor) * scale_factor
width = max(scale_factor, width)
height = max(scale_factor, height)
width = max(8, (width // 8) * 8)
height = max(8, (height // 8) * 8)
latent_width = width // scale_factor
latent_height = height // scale_factor
device = vae.device if hasattr(vae, 'device') else torch.device('cpu')
dtype = vae.dtype if hasattr(vae, 'dtype') else torch.float32
latent = torch.zeros(
[batch_size, latent_channels, latent_height, latent_width],
device=device,
dtype=dtype
)
return ({"samples": latent}, width, height)
NODE_CLASS_MAPPINGS = {
"RS_Image_MultiLatent": RS_Image_MultiLatent
}
NODE_DISPLAY_NAME_MAPPINGS = {
"RS_Image_MultiLatent": "🦊 RS Image MultiLatent"
}