From eef1907b11e8360d61acc12a9a202b51dbb2e815 Mon Sep 17 00:00:00 2001 From: Budi Hartono Date: Sat, 7 Jun 2025 21:40:39 +0700 Subject: [PATCH] Change Widget to Dropdowns --- __init__.py | 6 +-- nodes.py | 119 ++++++++++++++++++++++++++++++++++++++-------------- 2 files changed, 90 insertions(+), 35 deletions(-) diff --git a/__init__.py b/__init__.py index fc42c54..09fe93f 100644 --- a/__init__.py +++ b/__init__.py @@ -1,12 +1,10 @@ -# comfyui-aspect-ratio-presets/__init__.py +# __init__.py from .nodes import empty_latent_preset, empty_latent_by_axis NODE_CLASS_MAPPINGS = { - # Display name : Python callable "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" \ No newline at end of file diff --git a/nodes.py b/nodes.py index e43afe8..8ad28f7 100644 --- a/nodes.py +++ b/nodes.py @@ -3,32 +3,49 @@ import numpy as np from .presets import PRESETS -def _validate_dim(v:int): +# ─── Helpers ────────────────────────────────────────────────────────── + +def _validate_dim(v: int): if v <= 0: raise ValueError("Dimension must be > 0") if v % 8 != 0: 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) - 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(): + # Build the list of dropdown labels: + choices = [ + f"{W}x{H} - {lbl.split()[0]} {model}" + for model, lbl, W, H in PRESETS + ] return { "required": { - "resolution_index": ( - "INT", { - "default": 0, - "choices": [ - f"{m} {w}×{h} ({lbl})" - for m,lbl,w,h in PRESETS - ] - } - ), - "batch_size": ("INT", {"default":1, "min":1}) + # A true dropdown of strings: + "preset": (choices,), + "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.CATEGORY = "ComfyUI Aspect Ratio Preset" -# --- Node 2 ----------------------------------------------------------- + +# ─── Node 2: By Axis ────────────────────────────────────────────────── ASPECT_CHOICES = [ - ("1:1 Square",(1,1)), ("3:2 Landscape",(3,2)), ("2:3 Portrait",(2,3)), - # ... etc ... + ("1:1 Square", (1, 1)), + ("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: - w_ratio,h_ratio = ASPECT_CHOICES[aspect_index][1] +def empty_latent_by_axis( + 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) if reference == "Width": - W,H = primary_dim, round(primary_dim * h_ratio / w_ratio) + W = primary_dim + H = round(primary_dim * hr / wr) 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) - 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(): return { "required": { - "primary_dim": ("INT", {"default":512, "min":8}), - "reference": ("STRING", {"default":"Width", "choices":["Width","Height"]}), - "aspect_index": ("INT", { - "default":0, - "choices":[lbl for lbl,_ in ASPECT_CHOICES] - }), - "batch_size": ("INT", {"default":1, "min":1}) + "primary_dim": ("INT", {"default": 512, "min": 8}), + # A true dropdown of strings: + "reference": (["Width", "Height"],), + "aspect_ratio": ([lbl for lbl, _ in ASPECT_CHOICES],), + "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.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" \ No newline at end of file