163 lines
5.6 KiB
Python
163 lines
5.6 KiB
Python
"""Align Image 🆎."""
|
|
|
|
from __future__ import annotations
|
|
|
|
from ._align_helpers import (
|
|
ALIGN_MODES,
|
|
CROP_POSITIONS,
|
|
PAD_FILLS,
|
|
PAD_POSITIONS,
|
|
align_image,
|
|
)
|
|
|
|
|
|
class AusBossAlignImage:
|
|
CATEGORY = "🆎 AusBoss/Image"
|
|
DESCRIPTION = (
|
|
"Snaps an image's width and height to a clean multiple of a number "
|
|
"you choose — 8, 16, 32, whatever the model wants. Qwen image "
|
|
"models, VAEs, and many samplers behave best on cleanly divisible "
|
|
"sizes. Resize rescales to the nearest multiple, crop trims down to "
|
|
"one from the anchor you pick, pad grows up to one with edge pixels "
|
|
"or a colour; the new size comes out as INTs for wiring into latent "
|
|
"nodes."
|
|
)
|
|
SEARCH_ALIASES = [
|
|
"align",
|
|
"multiple of 8",
|
|
"multiple of 16",
|
|
"divisible",
|
|
"divisible by",
|
|
"snap size",
|
|
"resize to multiple",
|
|
"image resize",
|
|
"qwen",
|
|
"ausboss",
|
|
]
|
|
|
|
@classmethod
|
|
def INPUT_TYPES(cls):
|
|
return {
|
|
"required": {
|
|
"image": (
|
|
"IMAGE",
|
|
{"tooltip": "BHWC image batch to align."},
|
|
),
|
|
"multiple": (
|
|
"INT",
|
|
{
|
|
"default": 16,
|
|
"min": 1,
|
|
"max": 1024,
|
|
"step": 1,
|
|
"tooltip": (
|
|
"Width and height come out divisible by this. 16 "
|
|
"or 32 suits most diffusion models; latent-space "
|
|
"nodes usually want at least 8."
|
|
),
|
|
},
|
|
),
|
|
"mode": (
|
|
list(ALIGN_MODES),
|
|
{
|
|
"default": "resize",
|
|
"tooltip": (
|
|
"How to reach the multiple. resize rescales to "
|
|
"the NEAREST multiple (slight stretch, keeps "
|
|
"every pixel's content). crop trims DOWN to the "
|
|
"next multiple at the chosen anchor (no "
|
|
"distortion, loses edges). pad adds edges UP to "
|
|
"the next multiple with edge pixels or a colour "
|
|
"(no distortion). A side "
|
|
"smaller than one multiple always grows to "
|
|
"exactly one."
|
|
),
|
|
},
|
|
),
|
|
},
|
|
"optional": {
|
|
"crop_position": (
|
|
list(CROP_POSITIONS),
|
|
{
|
|
"default": "center",
|
|
"tooltip": (
|
|
"Crop mode only: which part of the frame "
|
|
"survives. center trims both edges evenly; top, "
|
|
"bottom, left, or right pin that edge and trim "
|
|
"the opposite one. Ignored by resize and pad."
|
|
),
|
|
},
|
|
),
|
|
"pad_position": (
|
|
list(PAD_POSITIONS),
|
|
{
|
|
"default": "center",
|
|
"tooltip": (
|
|
"Pad mode only: where the image sits on the "
|
|
"grown canvas — the new pixels land on the "
|
|
"opposite side. center splits them evenly."
|
|
),
|
|
},
|
|
),
|
|
"pad_fill": (
|
|
list(PAD_FILLS),
|
|
{
|
|
"default": "replicate",
|
|
"tooltip": (
|
|
"Pad mode only: what fills the new area. "
|
|
"replicate stretches the edge pixels out; color "
|
|
"uses pad_color as a solid."
|
|
),
|
|
},
|
|
),
|
|
"pad_color": (
|
|
"STRING",
|
|
{
|
|
"default": "#000000",
|
|
"tooltip": (
|
|
"Solid fill for pad_fill: color. Hex, R,G,B "
|
|
"numbers, or a CSS color name."
|
|
),
|
|
},
|
|
),
|
|
},
|
|
}
|
|
|
|
RETURN_TYPES = ("IMAGE", "INT", "INT")
|
|
RETURN_NAMES = ("image", "width", "height")
|
|
OUTPUT_TOOLTIPS = (
|
|
"The aligned batch; both sides are multiples of the chosen number.",
|
|
"Aligned width in pixels.",
|
|
"Aligned height in pixels.",
|
|
)
|
|
FUNCTION = "align"
|
|
|
|
def align(
|
|
self,
|
|
image,
|
|
multiple,
|
|
mode,
|
|
crop_position="center",
|
|
pad_position="center",
|
|
pad_fill="replicate",
|
|
pad_color="#000000",
|
|
):
|
|
# The helper also reports where the original landed; the node keeps
|
|
# its face to the three outputs a graph actually wires.
|
|
aligned, width, height, _offset_x, _offset_y = align_image(
|
|
image,
|
|
int(multiple),
|
|
str(mode),
|
|
str(crop_position),
|
|
str(pad_position),
|
|
str(pad_fill),
|
|
pad_color,
|
|
)
|
|
return (aligned, width, height)
|
|
|
|
|
|
NODE_CLASS_MAPPINGS = {"AUSBOSS_NODES_AlignImage": AusBossAlignImage}
|
|
NODE_DISPLAY_NAME_MAPPINGS = {"AUSBOSS_NODES_AlignImage": "Align Image 🆎"}
|
|
|
|
__all__ = ["NODE_CLASS_MAPPINGS", "NODE_DISPLAY_NAME_MAPPINGS"]
|