Change Widget to Dropdowns

This commit is contained in:
Budi Hartono
2025-06-07 21:40:39 +07:00
parent b728681a37
commit eef1907b11
2 changed files with 90 additions and 35 deletions
+2 -4
View File
@@ -1,12 +1,10 @@
# comfyui-aspect-ratio-presets/__init__.py # __init__.py
from .nodes import empty_latent_preset, empty_latent_by_axis from .nodes import empty_latent_preset, empty_latent_by_axis
NODE_CLASS_MAPPINGS = { NODE_CLASS_MAPPINGS = {
# Display name : Python callable
"Empty Latent (Aspect Ratio Preset)": empty_latent_preset, "Empty Latent (Aspect Ratio Preset)": empty_latent_preset,
"Empty Latent (Aspect Ratio by Axis)": empty_latent_by_axis, "Empty Latent (Aspect Ratio by Axis)": empty_latent_by_axis,
} }
# This is the category under which they appear in the ComfyUI UI
NODE_DISPLAY_NAME = "ComfyUI Aspect Ratio Preset" NODE_DISPLAY_NAME = "ComfyUI Aspect Ratio Preset"
+88 -31
View File
@@ -3,32 +3,49 @@
import numpy as np import numpy as np
from .presets import PRESETS from .presets import PRESETS
def _validate_dim(v:int): # ─── Helpers ──────────────────────────────────────────────────────────
def _validate_dim(v: int):
if v <= 0: if v <= 0:
raise ValueError("Dimension must be > 0") raise ValueError("Dimension must be > 0")
if v % 8 != 0: if v % 8 != 0:
raise ValueError("Dimension must be divisible by 8") raise ValueError("Dimension must be divisible by 8")
# --- Node 1 ----------------------------------------------------------- # ─── Node 1: Preset ───────────────────────────────────────────────────
def empty_latent_preset(
preset: str,
batch_size: int
) -> np.ndarray:
"""
Empty Latent (Aspect Ratio Preset)
preset: e.g. "512x512 - 1:1 SD 1.5"
batch_size: how many latents to produce
"""
# find matching entry
for model, lbl, W, H in PRESETS:
key = f"{W}x{H} - {lbl.split()[0]} {model}"
if key == preset:
break
else:
raise ValueError(f"Unknown preset: {preset}")
def empty_latent_preset(resolution_index:int, batch_size:int) -> np.ndarray:
model, label, W, H = PRESETS[resolution_index]
_validate_dim(W); _validate_dim(H) _validate_dim(W); _validate_dim(H)
return np.zeros((batch_size, 4, H//8, W//8), dtype=np.float32) return np.zeros((batch_size, 4, H // 8, W // 8), dtype=np.float32)
def _preset_input_types(): def _preset_input_types():
# Build the list of dropdown labels:
choices = [
f"{W}x{H} - {lbl.split()[0]} {model}"
for model, lbl, W, H in PRESETS
]
return { return {
"required": { "required": {
"resolution_index": ( # A true dropdown of strings:
"INT", { "preset": (choices,),
"default": 0, "batch_size": ("INT", {"default": 1, "min": 1})
"choices": [
f"{m} {w}×{h} ({lbl})"
for m,lbl,w,h in PRESETS
]
}
),
"batch_size": ("INT", {"default":1, "min":1})
} }
} }
@@ -36,33 +53,66 @@ empty_latent_preset.INPUT_TYPES = _preset_input_types
empty_latent_preset.RETURN_TYPES = ("LATENT",) empty_latent_preset.RETURN_TYPES = ("LATENT",)
empty_latent_preset.CATEGORY = "ComfyUI Aspect Ratio Preset" empty_latent_preset.CATEGORY = "ComfyUI Aspect Ratio Preset"
# --- Node 2 -----------------------------------------------------------
# ─── Node 2: By Axis ──────────────────────────────────────────────────
ASPECT_CHOICES = [ ASPECT_CHOICES = [
("1:1 Square",(1,1)), ("3:2 Landscape",(3,2)), ("2:3 Portrait",(2,3)), ("1:1 Square", (1, 1)),
# ... etc ... ("3:2 Landscape", (3, 2)),
("2:3 Portrait", (2, 3)),
("4:3 Landscape", (4, 3)),
("3:4 Portrait", (3, 4)),
("16:9 Landscape", (16, 9)),
("9:16 Portrait", (9, 16)),
("5:4 Landscape", (5, 4)),
("4:5 Portrait", (4, 5)),
("21:9 Widescreen",(21, 9)),
("9:21 Portrait", (9, 21)),
("7:5 Landscape", (7, 5)),
("5:7 Portrait", (5, 7)),
] ]
def empty_latent_by_axis(primary_dim:int, reference:str, aspect_index:int, batch_size:int) -> np.ndarray: def empty_latent_by_axis(
w_ratio,h_ratio = ASPECT_CHOICES[aspect_index][1] primary_dim: int,
reference: str,
aspect_ratio: str,
batch_size: int
) -> np.ndarray:
"""
Empty Latent (Aspect Ratio by Axis)
primary_dim: numeric value for Width or Height
reference: "Width" or "Height"
aspect_ratio: e.g. "3:2 Landscape"
batch_size: how many latents to produce
"""
# Look up numeric ratio
for lbl, (wr, hr) in ASPECT_CHOICES:
if lbl == aspect_ratio:
break
else:
raise ValueError(f"Unknown aspect ratio: {aspect_ratio}")
_validate_dim(primary_dim) _validate_dim(primary_dim)
if reference == "Width": if reference == "Width":
W,H = primary_dim, round(primary_dim * h_ratio / w_ratio) W = primary_dim
H = round(primary_dim * hr / wr)
else: else:
H,W = primary_dim, round(primary_dim * w_ratio / h_ratio) H = primary_dim
W = round(primary_dim * wr / hr)
_validate_dim(W); _validate_dim(H) _validate_dim(W); _validate_dim(H)
return np.zeros((batch_size, 4, H//8, W//8), dtype=np.float32) return np.zeros((batch_size, 4, H // 8, W // 8), dtype=np.float32)
def _byaxis_input_types(): def _byaxis_input_types():
return { return {
"required": { "required": {
"primary_dim": ("INT", {"default":512, "min":8}), "primary_dim": ("INT", {"default": 512, "min": 8}),
"reference": ("STRING", {"default":"Width", "choices":["Width","Height"]}), # A true dropdown of strings:
"aspect_index": ("INT", { "reference": (["Width", "Height"],),
"default":0, "aspect_ratio": ([lbl for lbl, _ in ASPECT_CHOICES],),
"choices":[lbl for lbl,_ in ASPECT_CHOICES] "batch_size": ("INT", {"default": 1, "min": 1})
}),
"batch_size": ("INT", {"default":1, "min":1})
} }
} }
@@ -70,4 +120,11 @@ empty_latent_by_axis.INPUT_TYPES = _byaxis_input_types
empty_latent_by_axis.RETURN_TYPES = ("LATENT",) empty_latent_by_axis.RETURN_TYPES = ("LATENT",)
empty_latent_by_axis.CATEGORY = "ComfyUI Aspect Ratio Preset" empty_latent_by_axis.CATEGORY = "ComfyUI Aspect Ratio Preset"
# ─── Expose for ComfyUI ────────────────────────────────────────────────
# ─── Expose for ComfyUI ───────────────────────────────────────────────
NODE_CLASS_MAPPINGS = {
"Empty Latent (Aspect Ratio Preset)": empty_latent_preset,
"Empty Latent (Aspect Ratio by Axis)": empty_latent_by_axis,
}
NODE_DISPLAY_NAME = "ComfyUI Aspect Ratio Preset"