Updates to naming and force div 16
Made naming more consistent and added a toggle to force divisible by 16.
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
# ComfyUI Wan Resolutions
|
||||
# ComfyUI WanResolutions
|
||||
|
||||
ComfyUI custom node that outputs `width` and `height` presets for Wan 2.2 video generation.
|
||||
|
||||
@@ -7,6 +7,7 @@ ComfyUI custom node that outputs `width` and `height` presets for Wan 2.2 video
|
||||
- Lets you choose an `aspect_ratio` and resolution quality tier
|
||||
- Outputs `INT` values: `width`, `height`
|
||||
- Optional `IMAGE` input auto-matches the closest supported aspect ratio as an override
|
||||
- Optional `round_to_16` snaps output to dimensions divisible by 16 while staying close to the target ratio
|
||||
- Keeps equivalent quality tier when you switch aspect ratios in the UI
|
||||
|
||||
Supported aspect ratios:
|
||||
@@ -34,10 +35,11 @@ Restart ComfyUI after installing.
|
||||
|
||||
## Usage
|
||||
|
||||
1. Add the `Wan Resolution` node.
|
||||
1. Add the `WanResolutions` node.
|
||||
2. Pick `aspect_ratio` and `resolution`.
|
||||
3. Optional: connect an `IMAGE` input to auto-select the nearest aspect ratio.
|
||||
4. Connect `width` and `height` outputs to your downstream nodes.
|
||||
3. Optional: enable `round_to_16` for dimensions divisible by 16.
|
||||
4. Optional: connect an `IMAGE` input to auto-select the nearest aspect ratio.
|
||||
5. Connect `width` and `height` outputs to your downstream nodes.
|
||||
|
||||
## License
|
||||
|
||||
|
||||
+3
-3
@@ -1,11 +1,11 @@
|
||||
from .wan_resolution import WanResolution
|
||||
from .wanresolutions import WanResolutions
|
||||
|
||||
NODE_CLASS_MAPPINGS = {
|
||||
"WanResolution": WanResolution,
|
||||
"WanResolutions": WanResolutions,
|
||||
}
|
||||
|
||||
NODE_DISPLAY_NAME_MAPPINGS = {
|
||||
"WanResolution": "Wan Resolution",
|
||||
"WanResolutions": "WanResolutions",
|
||||
}
|
||||
|
||||
# Any .js files in this directory will be loaded by the frontend
|
||||
|
||||
@@ -115,9 +115,9 @@ function tierIndexForValue(aspectRatio, value) {
|
||||
}
|
||||
|
||||
app.registerExtension({
|
||||
name: "wan_resolution.dynamic_resolution_list",
|
||||
name: "wanresolutions.dynamic_resolution_list",
|
||||
async nodeCreated(node) {
|
||||
if (node.comfyClass !== "WanResolution") return;
|
||||
if (node.comfyClass !== "WanResolutions") return;
|
||||
|
||||
const aspectWidget = node.widgets?.find((w) => w.name === "aspect_ratio");
|
||||
const resWidget = node.widgets?.find((w) => w.name === "resolution");
|
||||
+3
-3
@@ -1,6 +1,6 @@
|
||||
[project]
|
||||
name = "comfyui-wan-resolutions"
|
||||
description = "ComfyUI custom node for selecting WAN resolution presets by aspect ratio."
|
||||
name = "comfyui-wanresolutions"
|
||||
description = "ComfyUI custom node for selecting Wan resolution presets by aspect ratio."
|
||||
authors = [
|
||||
{ name = "boobkake22", email = "boobkake22@gmail.com" }
|
||||
]
|
||||
@@ -16,5 +16,5 @@ Repository = "https://github.com/boobkake22/ComfyUI-WanResolutions"
|
||||
|
||||
[tool.comfy]
|
||||
PublisherId = "boobkake22"
|
||||
DisplayName = "Wan Resolutions"
|
||||
DisplayName = "WanResolutions"
|
||||
Icon = ""
|
||||
|
||||
@@ -2,11 +2,12 @@ import re
|
||||
from typing import Dict, List, Optional, Tuple
|
||||
|
||||
|
||||
class WanResolution:
|
||||
class WanResolutions:
|
||||
"""
|
||||
WAN Resolution
|
||||
WanResolutions
|
||||
- Choose aspect ratio and quality tier.
|
||||
- Optional IMAGE input can auto-select the closest aspect ratio.
|
||||
- Optional round_to_16 can snap output dimensions to multiples of 16.
|
||||
- Outputs width,height as INT.
|
||||
"""
|
||||
|
||||
@@ -124,6 +125,7 @@ class WanResolution:
|
||||
"required": {
|
||||
"aspect_ratio": (aspect_choices, {"default": default_ar}),
|
||||
"resolution": (all_resolution_choices, {"default": default_res}),
|
||||
"round_to_16": ("BOOLEAN", {"default": False}),
|
||||
},
|
||||
"optional": {
|
||||
"image": ("IMAGE",),
|
||||
@@ -166,6 +168,63 @@ class WanResolution:
|
||||
w, h, _ = rows[0]
|
||||
return w, h
|
||||
|
||||
@staticmethod
|
||||
def _round_to_multiple(value: float, multiple: int) -> int:
|
||||
if multiple <= 0:
|
||||
return int(round(value))
|
||||
return max(multiple, int(round(float(value) / float(multiple))) * multiple)
|
||||
|
||||
@classmethod
|
||||
def _round_resolution_preserve_aspect(
|
||||
cls,
|
||||
width: int,
|
||||
height: int,
|
||||
multiple: int = 16,
|
||||
) -> Tuple[int, int]:
|
||||
"""
|
||||
Snap dimensions to a required multiple while keeping aspect ratio as close
|
||||
as possible to the requested width/height.
|
||||
"""
|
||||
if width <= 0 or height <= 0:
|
||||
return (
|
||||
cls._round_to_multiple(max(1, width), multiple),
|
||||
cls._round_to_multiple(max(1, height), multiple),
|
||||
)
|
||||
|
||||
target_ratio = float(width) / float(height)
|
||||
target_area = width * height
|
||||
|
||||
base_w = cls._round_to_multiple(width, multiple)
|
||||
base_h = cls._round_to_multiple(height, multiple)
|
||||
|
||||
width_candidates = {max(multiple, base_w + (step * multiple)) for step in range(-3, 4)}
|
||||
height_candidates = {max(multiple, base_h + (step * multiple)) for step in range(-3, 4)}
|
||||
|
||||
candidates = set()
|
||||
|
||||
# Generate options by preserving ratio from width and from height.
|
||||
for w in width_candidates:
|
||||
h = cls._round_to_multiple(float(w) / target_ratio, multiple)
|
||||
candidates.add((w, h))
|
||||
for h in height_candidates:
|
||||
w = cls._round_to_multiple(float(h) * target_ratio, multiple)
|
||||
candidates.add((w, h))
|
||||
|
||||
# Add a small local grid around the nearest rounded size.
|
||||
for w in width_candidates:
|
||||
for h in height_candidates:
|
||||
candidates.add((w, h))
|
||||
|
||||
best_w, best_h = min(
|
||||
candidates,
|
||||
key=lambda wh: (
|
||||
abs((float(wh[0]) / float(wh[1])) - target_ratio),
|
||||
abs(wh[0] - width) + abs(wh[1] - height),
|
||||
abs((wh[0] * wh[1]) - target_area),
|
||||
),
|
||||
)
|
||||
return int(best_w), int(best_h)
|
||||
|
||||
@staticmethod
|
||||
def _parse_aspect_ratio_value(aspect_ratio: str) -> Optional[float]:
|
||||
m = re.match(r"^\s*(\d+)\s*:\s*(\d+)\s*$", aspect_ratio or "")
|
||||
@@ -234,6 +293,7 @@ class WanResolution:
|
||||
aspect_ratio: str,
|
||||
resolution: str,
|
||||
image=None,
|
||||
round_to_16: bool = False,
|
||||
):
|
||||
resolved_aspect = aspect_ratio
|
||||
image_dims = self._image_dimensions(image)
|
||||
@@ -242,4 +302,6 @@ class WanResolution:
|
||||
resolved_aspect = self._best_aspect_ratio(image_w, image_h)
|
||||
|
||||
w, h = self._parse_resolution(resolved_aspect, resolution)
|
||||
if round_to_16:
|
||||
w, h = self._round_resolution_preserve_aspect(w, h, multiple=16)
|
||||
return (int(w), int(h))
|
||||
Reference in New Issue
Block a user