diff --git a/__init__.py b/__init__.py index ad3990d..5a5f917 100644 --- a/__init__.py +++ b/__init__.py @@ -3,6 +3,7 @@ from .flux_sampler_node import FluxSampler from .flux_controlnet_node import FluxControlNetApply from .boolean_basic_node import BooleanBasic from .boolean_reverse_node import BooleanReverse +from .get_image_size_ratio_node import GetImageSizeRatio print("Initializing ControlAltAI Nodes") @@ -12,6 +13,7 @@ NODE_CLASS_MAPPINGS = { "FluxControlNetApply": FluxControlNetApply, "BooleanBasic": BooleanBasic, "BooleanReverse": BooleanReverse, + "GetImageSizeRatio": GetImageSizeRatio } NODE_DISPLAY_NAME_MAPPINGS = { @@ -20,4 +22,5 @@ NODE_DISPLAY_NAME_MAPPINGS = { "FluxControlNetApply": "Flux ControlNet", "BooleanBasic": "Boolean Basic", "BooleanReverse": "Boolean Reverse", + "GetImageSizeRatio": "Get Image Size & Ratio" } \ No newline at end of file diff --git a/flux_resolution_cal_node.py b/flux_resolution_cal_node.py index a2bc8f4..1c03ba8 100644 --- a/flux_resolution_cal_node.py +++ b/flux_resolution_cal_node.py @@ -11,6 +11,10 @@ class FluxResolutionNode: "3:2 (Golden Landscape)", "4:3 (Classic Landscape)", "5:3 (Wide Horizon)", "5:4 (Balanced Frame)", "7:5 (Elegant Landscape)", "8:5 (Cinematic View)", "9:7 (Artful Horizon)", "16:9 (Panorama)", "19:9 (Cinematic Ultrawide)", "21:9 (Epic Ultrawide)", "32:9 (Extreme Ultrawide)" ], {"default": "1:1 (Perfect Square)"}), + "custom_ratio": ("BOOLEAN", {"default": False, "label_on": "Enable", "label_off": "Disable"}), + }, + "optional": { + "custom_aspect_ratio": ("STRING", {"default": "1:1"}), } } @@ -20,27 +24,34 @@ class FluxResolutionNode: CATEGORY = "ControlAltAI Nodes/Flux" OUTPUT_NODE = True - def calculate_dimensions(self, megapixel, aspect_ratio): + def calculate_dimensions(self, megapixel, aspect_ratio, custom_ratio, custom_aspect_ratio=None): megapixel = float(megapixel) - # Extract the numeric ratio - numeric_ratio = aspect_ratio.split(' ')[0] + + if custom_ratio and custom_aspect_ratio: + numeric_ratio = custom_aspect_ratio + else: + numeric_ratio = aspect_ratio.split(' ')[0] + width_ratio, height_ratio = map(int, numeric_ratio.split(':')) + total_pixels = megapixel * 1_000_000 dimension = (total_pixels / (width_ratio * height_ratio)) ** 0.5 width = int(dimension * width_ratio) height = int(dimension * height_ratio) - # Determine rounding factor based on megapixel value - if megapixel in [0.1, 0.5, 1.0, 1.5]: + # Apply rounding logic based on megapixel value + if megapixel in [0.1, 0.5]: round_to = 8 - if megapixel in [1.0, 1.5]: + elif megapixel in [1.0, 1.5]: round_to = 64 else: # 2.0 and above round_to = 32 + width = round(width / round_to) * round_to height = round(height / round_to) * round_to resolution = f"{width} x {height}" + return width, height, resolution NODE_CLASS_MAPPINGS = { @@ -49,4 +60,4 @@ NODE_CLASS_MAPPINGS = { NODE_DISPLAY_NAME_MAPPINGS = { "FluxResolutionNode": "Flux Resolution Calculator", -} +} \ No newline at end of file diff --git a/get_image_size_ratio_node.py b/get_image_size_ratio_node.py new file mode 100644 index 0000000..c3781fc --- /dev/null +++ b/get_image_size_ratio_node.py @@ -0,0 +1,38 @@ +class GetImageSizeRatio: + @classmethod + def INPUT_TYPES(cls): + return { + "required": { + "image": ("IMAGE",) + } + } + + RETURN_TYPES = ("INT", "INT", "STRING") + RETURN_NAMES = ("width", "height", "ratio") + FUNCTION = "get_image_size_ratio" + + CATEGORY = "ControlAltAI Nodes/Image" + + def get_image_size_ratio(self, image): + _, height, width, _ = image.shape + + gcd = self.greatest_common_divisor(width, height) + ratio_width = width // gcd + ratio_height = height // gcd + + ratio = f"{ratio_width}:{ratio_height}" + + return width, height, ratio + + def greatest_common_divisor(self, a, b): + while b != 0: + a, b = b, a % b + return a + +NODE_CLASS_MAPPINGS = { + "GetImageSizeRatio": GetImageSizeRatio, +} + +NODE_DISPLAY_NAME_MAPPINGS = { + "GetImageSizeRatio": "Get Image Size & Ratio", +} \ No newline at end of file