Merge pull request #2 from Meettya/feat/latent-scale-factor-config

Feat/latent scale factor config
This commit is contained in:
Karpich Dmitry
2026-04-26 05:31:16 +03:00
committed by GitHub
6 changed files with 66 additions and 31 deletions
+1 -1
View File
@@ -1,6 +1,6 @@
MIT License
Copyright (c) 2025 Karpich Dmitry
Copyright (c) 2025-2026 Karpich Dmitry
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
+3 -3
View File
@@ -2,17 +2,17 @@
## Image Fit Calculator
<img src="https://github.com/Meettya/ComfyUI-OneForOne-Demo/blob/b1f3ffa041d9b1f615553bb29ea2f74ded8b3b8b/examples/fit_calculator_node.jpg?raw=true" alt="Image Fit Calculator node" style="width: 50%; height: auto; display: block; margin-left: auto; margin-right: auto;">
<img src="https://github.com/Meettya/ComfyUI-OneForOne-Demo/blob/cfc49d3046acfc5e6d8c1e68a2dc3662d2f36475/examples/fit_calculator_node.jpg?raw=true" alt="Image Fit Calculator node" style="width: 50%; height: auto; display: block; margin-left: auto; margin-right: auto;">
<br/>
The ComfyUI custom node **Image Fit Calculator** is designed to automatically calculate new image parameters based on a given latent and original image. Specifically, this node can perform calculations for resizing an image and provide data for paddings to control its placement within the latent space. Additionally, it includes settings that allow users to specify horizontal or vertical offsets as well as reduce the size of the image. This node performs only computational tasks, while actual operations on the image may be carried out by external nodes if they have the capability to use input data to manipulate the result.
<img src="https://github.com/Meettya/ComfyUI-OneForOne-Demo/blob/b1f3ffa041d9b1f615553bb29ea2f74ded8b3b8b/examples/fit_calculator.jpg?raw=true" alt="Image Fit Calculator example" style="display: block; margin-left: auto; margin-right: auto;">
<img src="https://github.com/Meettya/ComfyUI-OneForOne-Demo/blob/cfc49d3046acfc5e6d8c1e68a2dc3662d2f36475/examples/fit_calculator.jpg?raw=true" alt="Image Fit Calculator example" style="display: block; margin-left: auto; margin-right: auto;">
In the provided workflow example, one can see how the ComfyUI node integrates with other components to streamline the process of image manipulation. This modular approach ensures flexibility and extensibility, enabling developers to easily incorporate new functionalities or optimize existing ones.
![Demo Animation](https://github.com/Meettya/ComfyUI-OneForOne-Demo/blob/0316b0b971aec47c097bf4389b16c213e6591038/examples/Fitcalcutator.gif?raw=true)
![Demo Animation](https://github.com/Meettya/ComfyUI-OneForOne-Demo/blob/cfc49d3046acfc5e6d8c1e68a2dc3662d2f36475/examples/Fitcalcutator.gif?raw=true)
If you encounter any bugs or have ideas for improving the ComfyUI node, feel free to create an issue or submit a pull request. Your contributions are highly appreciated and will help enhance this powerful tool for image processing automation.
+51 -14
View File
@@ -1,7 +1,15 @@
from numpy import ndarray
from typing import Union
from .util import get_sizes
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:
@@ -11,7 +19,11 @@ class OFOImageFit:
@classmethod
def INPUT_TYPES(s):
return {
"required": {"latent": ("LATENT",), "image": ("IMAGE",)},
"required": {
"latent": ("LATENT",),
"image": ("IMAGE",),
"latent_scale": (SCALE_OPTIONS, {"default": SCALE_8X}),
},
"optional": {
"width_position": (
"FLOAT",
@@ -76,6 +88,7 @@ class OFOImageFit:
self,
latent: Union[dict, ndarray],
image: ndarray,
latent_scale: str,
width_position: float = 0.5,
height_position: float = 0.5,
scale: float = 1.0,
@@ -86,6 +99,7 @@ class OFOImageFit:
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.
@@ -93,24 +107,47 @@ class OFOImageFit:
Returns:
tuple: A tuple containing six integers representing the new width, height, top, right, bottom, and left padding values.
"""
# get sizes
latent_height, latent_width = get_sizes(latent)
image_height, image_width = get_sizes(image)
scale_factor = SCALE_FACTOR_MAP[latent_scale]
# get minimum 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
# scale image
new_image_width = round(image_width * min_scale)
new_image_height = round(image_height * min_scale)
# Initial candidate dimensions (floored to avoid exceeding latent)
raw_width = int(image_width * min_scale)
raw_height = int(image_height * min_scale)
# calculate padding
padding_left = round((latent_width - new_image_width) * width_position)
padding_right = latent_width - new_image_width - padding_left
padding_bottom = round((latent_height - new_image_height) * height_position)
padding_top = latent_height - new_image_height - padding_bottom
# 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,
+9 -11
View File
@@ -1,14 +1,12 @@
from numpy import ndarray
from typing import Union, Tuple
# latent to pixel scale factor
SCALE = 8
from typing import Tuple
def get_sizes(target: Union[dict, ndarray]) -> Tuple[int, int]:
if isinstance(target, dict) and "samples" in target:
# Latent height, width
return (target["samples"].shape[2] * SCALE, target["samples"].shape[3] * SCALE)
else:
# Image height, width
return (target.shape[1], target.shape[2])
def get_latent_size(latent: dict, scale_factor: int = 8) -> Tuple[int, int]:
"""Convert latent dimensions to pixel dimensions using scale factor."""
return (latent["samples"].shape[2] * scale_factor, latent["samples"].shape[3] * scale_factor)
def get_image_size(image: ndarray) -> Tuple[int, int]:
"""Get image height and width from numpy array."""
return (image.shape[1], image.shape[2])
+1 -1
View File
@@ -1,7 +1,7 @@
[project]
name = "comfyui-oneforone"
description = "Node:Image Fit Calculator"
version = "1.0.1"
version = "2.0.1"
license = {file = "LICENSE"}
dependencies = ["numpy"]
File diff suppressed because one or more lines are too long