Files

98 lines
3.9 KiB
Python

# encoding: utf-8
"""
Nodes to calculate crop / padding values (for out-paint).
"""
from inspect import cleandoc as _cleandoc
from comfy_api.latest import io as _io
from . import _io_enum as _enums
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_crop_pad import upscaled_crop_pad as _upscaled_crop_pad
# ----------------------------------------------------------
class BRUpscaledCropPad(_io.ComfyNode):
"""
If the original resolution can't be scaled to the higher one uniformly (i.e., without stretching),
this node detects the appropriate values for cropping/out-painting.
"""
_schema = _io.Schema(
'BestResolutionUpscaledCropPad',
display_name="Upscaled Crop/Pad (Best-Res)",
category=_meta.category,
description=_format_docstring(_cleandoc(__doc__)),
inputs=[
_io_override(_i.upscale, tooltip=f"Only used when {_enums.UpscaledCropPadStrategy.EXACT_UPSCALE!r} strategy selected."),
_io_override(_i.res, 'init_width', tooltip=_tt.init_width),
_io_override(_i.res, 'init_height', tooltip=_tt.init_height),
_io_override(_i.res, 'HD_width', default=1536, tooltip=_tt.HD_width),
_io_override(_i.res, 'HD_height', default=1536, tooltip=_tt.HD_height),
_enums.crop_pad_strategy_in,
_io_override(_i.rel_pos, 'align_x', tooltip=(
"Where's the image pivot for horizontal alignment (which side stays in place during crop/out-paint):\n"
"0 - Left\n"
"0.5 - Center\n"
"1 - Right"
)),
_io_override(_i.rel_pos, 'align_y', default=0.0, tooltip=(
"Where's the image pivot for vertical alignment (which side stays in place during crop/out-paint):\n"
"0 - Bottom\n"
"0.5 - Center\n"
"1 - Top"
)),
],
hidden=[_io.Hidden.unique_id],
outputs=[
# In v3 schema, IDs must be unique between BOTH lists: inputs and outputs, so uppercase ID + `display_name`:
_io.Float.Output('UPSCALE', display_name='upscale', tooltip="The actual uniform upscale value to do."),
# Once we have a single ID in the list, we need to specify all the display names.
# Without it, outputs will be drawn with their types.
_io.Boolean.Output('do_crop', display_name='do_crop', tooltip="Whether post-upscale crop needs to be done to get the specified resolution."),
_io.Int.Output('crop_width', display_name='crop_width', tooltip="Width for the post-upscale crop."),
_io.Int.Output('crop_height', display_name='crop_height', tooltip="Height for the post-upscale crop."),
_io.Int.Output('crop_x', display_name='crop_x', tooltip="X-offset for the post-upscale crop."),
_io.Int.Output('crop_y', display_name='crop_y', tooltip="Y-offset for the post-upscale crop."),
_io.Boolean.Output('do_padding', display_name='do_padding', tooltip="Whether post-upscale padding and out-paint need to be done to get the specified resolution."),
_io.Int.Output('pad_left', display_name='pad_left', tooltip="Left padding for the post-upscale out-paint."),
_io.Int.Output('pad_top', display_name='pad_top', tooltip="Top padding for the post-upscale out-paint."),
_io.Int.Output('pad_right', display_name='pad_right', tooltip="Right padding for the post-upscale out-paint."),
_io.Int.Output('pad_bottom', display_name='pad_bottom', tooltip="Bottom padding for the post-upscale out-paint."),
],
is_output_node=True,
)
@classmethod
def define_schema(cls) -> _io.Schema:
return cls._schema
@classmethod
def execute(
cls,
upscale: float,
init_width: int, init_height: int, HD_width: int, HD_height: int,
strategy: _enums.UpscaledCropPadStrategy | str,
align_x: float, align_y: float,
# show: bool,
) -> _io.NodeOutput:
return _io.NodeOutput(
*_upscaled_crop_pad(
upscale,
init_width, init_height, HD_width, HD_height,
_enums.UpscaledCropPadStrategy.validate(strategy),
align_x, align_y,
# show,
unique_id=cls.hidden.unique_id
)
)