* Add MegapixelScale node to scale width/height to a target megapixel count Scales width and height so total pixels match the given megapixels input while preserving the original aspect ratio. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Es1PqnGyFk9U2mngaWxgNg * Round MegapixelScale output to nearest multiple of 8 Diffusion models generally require width/height divisible by 8, so snap the scaled dimensions directly instead of leaving raw rounding. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Es1PqnGyFk9U2mngaWxgNg --------- Co-authored-by: Claude <noreply@anthropic.com>
40 lines
1.4 KiB
Python
40 lines
1.4 KiB
Python
"""ComfyUI custom node for scaling width/height to a target megapixel count."""
|
|
import math
|
|
|
|
ROUND_TO_MULTIPLE = 8
|
|
|
|
|
|
class MegapixelScaleNode:
|
|
@classmethod
|
|
def INPUT_TYPES(cls):
|
|
return {
|
|
"required": {
|
|
"width": ("INT", {"default": 512, "min": 1, "max": 1_000_000}),
|
|
"height": ("INT", {"default": 512, "min": 1, "max": 1_000_000}),
|
|
"megapixels": ("FLOAT", {"default": 1.0, "min": 0.01, "max": 100.0, "step": 0.01}),
|
|
},
|
|
}
|
|
|
|
CATEGORY = "Feroc"
|
|
RETURN_TYPES = ("INT", "INT")
|
|
RETURN_NAMES = ("width", "height")
|
|
FUNCTION = "scale"
|
|
|
|
def scale(self, width: int, height: int, megapixels: float) -> tuple[int, int]:
|
|
"""Scale width/height to the target megapixel count, preserving aspect ratio.
|
|
|
|
Results are rounded to the nearest multiple of 8 for compatibility with
|
|
diffusion models that require dimensions divisible by 8.
|
|
"""
|
|
target_pixels = megapixels * 1_000_000
|
|
scale_factor = math.sqrt(target_pixels / (width * height))
|
|
|
|
new_width = self._round_to_multiple(width * scale_factor)
|
|
new_height = self._round_to_multiple(height * scale_factor)
|
|
|
|
return (new_width, new_height)
|
|
|
|
@staticmethod
|
|
def _round_to_multiple(value: float, multiple: int = ROUND_TO_MULTIPLE) -> int:
|
|
return max(multiple, round(value / multiple) * multiple)
|