Files
Lex-DRL-ComfyUI-BestResolution/nodes_simple.py
T
2026-04-16 06:31:26 -03:00

180 lines
5.0 KiB
Python

# encoding: utf-8
"""
Simple (aka no-upscale) versions of nodes.
"""
from inspect import cleandoc as _cleandoc
from math import sqrt as _sqrt
from comfy_api.latest import io as _io
from . import _io_simple as _i
from ._io_simple import _io_override
from . import _meta
from . import _tooltips as _tt
from .docstring_formatter import format_docstring as _format_docstring
from .funcs import (
aspect_ratios_sorted as _aspect_ratios_sorted,
number_to_int as _number_to_int,
float_width_height_from_area as _float_width_height_from_area,
simple_result_from_approx_wh as _simple_result_from_approx_wh
)
# ----------------------------------------------------------
class BestResolutionSimple(_io.ComfyNode):
"""
The simplest node for easier selection of an optimal resolution:
only rounding performed, desired image size specified directly.
"""
_schema = _io.Schema(
'BestResolutionSimple',
display_name="Best-Res (simple)",
category=_meta.category,
description=_format_docstring(_cleandoc(__doc__)),
inputs=[
_io_override(_i.res, 'width', tooltip="Approximate width"),
_io_override(_i.res, 'height', tooltip="Approximate height"),
_io_override(_i.step_init, 'step'),
],
hidden=[_io.Hidden.unique_id],
outputs=[
_io.Int.Output('WIDTH', display_name='width'),
_io.Int.Output('HEIGHT', display_name='height'),
],
is_output_node=True,
)
@classmethod
def define_schema(cls) -> _io.Schema:
return cls._schema
@classmethod
def execute(
cls,
width: int, height: int, step: int,
# show: bool,
) -> _io.NodeOutput:
return _io.NodeOutput(*_simple_result_from_approx_wh(
float(width), height, step,
# show,
unique_id=cls.hidden.unique_id, target_square_size=_sqrt(width * height)
))
# ----------------------------------------------------------
class BestResolutionFromAspectRatio(_io.ComfyNode):
"""
A more advanced node for easier selection of an optimal resolution:
image size selected indirectly - by one of the sides + aspect ratio.
"""
_schema = _io.Schema(
'BestResolutionFromAspectRatio',
display_name="Best-Res (ratio)",
category=_meta.category,
description=_format_docstring(_cleandoc(__doc__)),
inputs=[
_io_override(_i.res, 'size', tooltip=_tt.size_one_side),
_io_override(_i.step_init, 'step'),
_i.toggle_size_is_big,
_i.toggle_landscape,
_i.aspect_a,
_i.aspect_b,
],
hidden=[_io.Hidden.unique_id],
outputs=list(BestResolutionSimple._schema.outputs),
is_output_node=True,
)
@classmethod
def define_schema(cls) -> _io.Schema:
return cls._schema
@classmethod
def execute(
cls,
size: int, step: int, size_is_big: bool, landscape: bool, aspect_a: float, aspect_b: float,
# show: bool,
) -> _io.NodeOutput:
aspect_big, aspect_small = _aspect_ratios_sorted(aspect_a, aspect_b)
side_main_f = float(size)
side_other_f = side_main_f * (
(aspect_small / aspect_big) if size_is_big else (aspect_big / aspect_small)
)
width_f, height_f = (side_other_f, side_main_f) if side_other_f > side_main_f else (side_main_f, side_other_f)
if not landscape:
# The opposite: height is bigger
width_f, height_f = height_f, width_f
return _io.NodeOutput(*_simple_result_from_approx_wh(
width_f, height_f, step,
# show,
unique_id=cls.hidden.unique_id, target_square_size=_sqrt(width_f * height_f)
))
# ----------------------------------------------------------
class BestResolutionFromArea(_io.ComfyNode):
"""
The most efficient way of selecting an optimal resolution:
image size selected indirectly - by the total desired resolution (area) + aspect ratio.
Desired resolution (aka image area/megapixels/pixel count) is specified with a side of a square image. This isn't
accidental: most models disclose what image resolution they're trained on, and usually they're square:
- SD 1.5 - 512x512 pixels
- SDXL - 1024x1024 pixels
By simply providing this single number and setting your aspect ratio/orientation, you get the width and height to
produce the closest total resolution to the training set, while also respecting image proportions and step-rounding.
"""
_schema = _io.Schema(
'BestResolutionFromArea',
display_name="Best-Res (area)",
category=_meta.category,
description=_format_docstring(_cleandoc(__doc__)),
inputs=[
_io_override(_i.res, 'square_size', tooltip=_tt.size_square),
_io_override(_i.step_init, 'step'),
_i.toggle_landscape,
_i.aspect_a,
_i.aspect_b,
],
hidden=[_io.Hidden.unique_id],
outputs=list(BestResolutionSimple._schema.outputs),
is_output_node=True,
)
@classmethod
def define_schema(cls) -> _io.Schema:
return cls._schema
@classmethod
def execute(
cls,
square_size: int, step: int, landscape: bool, aspect_a: float, aspect_b: float,
# show: bool,
) -> _io.NodeOutput:
square_size: int = _number_to_int(square_size)
width_f, height_f = _float_width_height_from_area(square_size, landscape, aspect_a, aspect_b)
return _io.NodeOutput(*_simple_result_from_approx_wh(
width_f, height_f, step,
# show,
unique_id=cls.hidden.unique_id, target_square_size=square_size
))