160 lines
5.3 KiB
Python
160 lines
5.3 KiB
Python
from numpy import ndarray
|
|
from typing import Union
|
|
|
|
from .util import get_latent_size, get_image_size
|
|
|
|
SCALE_8X = "SD, Qwen (8x)"
|
|
SCALE_16X = "Flux2 (16x)"
|
|
SCALE_OPTIONS = [SCALE_8X, SCALE_16X]
|
|
SCALE_FACTOR_MAP = {
|
|
SCALE_8X: 8,
|
|
SCALE_16X: 16,
|
|
}
|
|
|
|
|
|
class OFOImageFit:
|
|
def __init__(self):
|
|
pass
|
|
|
|
@classmethod
|
|
def INPUT_TYPES(s):
|
|
return {
|
|
"required": {
|
|
"latent": ("LATENT",),
|
|
"image": ("IMAGE",),
|
|
"latent_scale": (SCALE_OPTIONS, {"default": SCALE_8X}),
|
|
},
|
|
"optional": {
|
|
"width_position": (
|
|
"FLOAT",
|
|
{
|
|
"default": 0.5,
|
|
"min": 0.0,
|
|
"max": 1.0,
|
|
"step": 0.01,
|
|
"round": 0.001,
|
|
"display": "number",
|
|
"lazy": True,
|
|
},
|
|
),
|
|
"height_position": (
|
|
"FLOAT",
|
|
{
|
|
"default": 0.5,
|
|
"min": 0.0,
|
|
"max": 1.0,
|
|
"step": 0.01,
|
|
"round": 0.001,
|
|
"display": "number",
|
|
"lazy": True,
|
|
},
|
|
),
|
|
"scale": (
|
|
"FLOAT",
|
|
{
|
|
"default": 1,
|
|
"min": 0.1,
|
|
"max": 1.0,
|
|
"step": 0.01,
|
|
"round": 0.01,
|
|
"display": "number",
|
|
"lazy": True,
|
|
},
|
|
),
|
|
},
|
|
}
|
|
|
|
RETURN_TYPES = (
|
|
"INT",
|
|
"INT",
|
|
"INT",
|
|
"INT",
|
|
"INT",
|
|
"INT",
|
|
)
|
|
RETURN_NAMES = (
|
|
"IMAGE_WIDTH",
|
|
"IMAGE_HEIGHT",
|
|
"PAD_TOP",
|
|
"PAD_RIGHT",
|
|
"PAD_BOTTOM",
|
|
"PAD_LEFT",
|
|
)
|
|
|
|
FUNCTION = "calculate"
|
|
CATEGORY = "OneForOne"
|
|
|
|
def calculate(
|
|
self,
|
|
latent: Union[dict, ndarray],
|
|
image: ndarray,
|
|
latent_scale: str,
|
|
width_position: float = 0.5,
|
|
height_position: float = 0.5,
|
|
scale: float = 1.0,
|
|
):
|
|
"""
|
|
Calculate new dimensions and paddings for image, based on latent and given parameters.
|
|
|
|
Args:
|
|
latent (np.ndarray or dict): Latent representation or dictionary containing latent samples.
|
|
image (np.ndarray): Input image to be resized and padded.
|
|
latent_scale (str): Latent scale factor option. "SD, Qwen (8x)" or "Flux2 (16x)".
|
|
width_position (float, optional): Horizontal position where the image will be placed within the latent space. Defaults to 0.5.
|
|
height_position (float, optional): Vertical position where the image will be placed within the latent space. Defaults to 0.5.
|
|
scale (float, optional): Scaling factor applied to the image before resizing. Defaults to 1.0.
|
|
|
|
Returns:
|
|
tuple: A tuple containing six integers representing the new width, height, top, right, bottom, and left padding values.
|
|
"""
|
|
scale_factor = SCALE_FACTOR_MAP[latent_scale]
|
|
|
|
latent_height, latent_width = get_latent_size(latent, scale_factor)
|
|
image_height, image_width = get_image_size(image)
|
|
|
|
# Compute base scaling (fit inside latent)
|
|
scale_w = latent_width / image_width
|
|
scale_h = latent_height / image_height
|
|
min_scale = min(scale_w, scale_h) * scale
|
|
|
|
# Initial candidate dimensions (floored to avoid exceeding latent)
|
|
raw_width = int(image_width * min_scale)
|
|
raw_height = int(image_height * min_scale)
|
|
|
|
# Ensure raw dimensions do not exceed latent bounds (safety)
|
|
raw_width = min(raw_width, latent_width)
|
|
raw_height = min(raw_height, latent_height)
|
|
|
|
# ----- Adjust to multiples of 8 -----
|
|
# We prefer rounding down to the nearest multiple of 8 (keep inside latent).
|
|
# But we also need to ensure we don't lose too much size.
|
|
# Let's find the largest multiple of 8 <= raw_width and <= raw_height.
|
|
target_width = (raw_width // 8) * 8
|
|
target_height = (raw_height // 8) * 8
|
|
|
|
# However, if the difference is too large (more than 7 pixels), we could try rounding up if still fits.
|
|
# But to be safe and keep exact fit, we just round down.
|
|
# If rounding down reduces size too much, the user can increase `scale`.
|
|
new_image_width = target_width
|
|
new_image_height = target_height
|
|
|
|
# ----- Recompute paddings based on final aligned sizes -----
|
|
# Horizontal padding
|
|
remaining_width = latent_width - new_image_width
|
|
padding_left = int(remaining_width * width_position)
|
|
padding_right = remaining_width - padding_left
|
|
|
|
# Vertical padding
|
|
remaining_height = latent_height - new_image_height
|
|
padding_top = int(remaining_height * height_position)
|
|
padding_bottom = remaining_height - padding_top
|
|
|
|
return (
|
|
new_image_width,
|
|
new_image_height,
|
|
padding_top,
|
|
padding_right,
|
|
padding_bottom,
|
|
padding_left,
|
|
)
|