From 4ccf4e8c1929c7f82b982cf525977be5883a83bd Mon Sep 17 00:00:00 2001 From: qwaezrx Date: Wed, 24 Jan 2024 17:10:57 +0900 Subject: [PATCH] Image Crop By Ratio added --- __init__.py | 3 ++ nodes/__init__.py | 2 + nodes/image_nodes.py | 106 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 111 insertions(+) create mode 100644 nodes/image_nodes.py diff --git a/__init__.py b/__init__.py index 8918eba..ce753e6 100644 --- a/__init__.py +++ b/__init__.py @@ -26,6 +26,8 @@ NODE_CLASS_MAPPINGS = { "CachedGetter": CachedGetter, "DragNUWAImageCanvas": DragNUWAImageCanvas, + + "ImageCropByRatio": ImageCropByRatio, } NODE_DISPLAY_NAME_MAPPINGS = { @@ -48,6 +50,7 @@ NODE_DISPLAY_NAME_MAPPINGS = { # "FlowBuilderSetter (adv)": END_EMOJI + "(adv) FlowBuilder", "DragNUWAImageCanvas": "DragNUWAImageCanvas", + "ImageCropByRatio": "ImageCropByRatio", } diff --git a/nodes/__init__.py b/nodes/__init__.py index 2f250a0..5cfb93c 100644 --- a/nodes/__init__.py +++ b/nodes/__init__.py @@ -4,6 +4,7 @@ from .cacheable_nodes import ( KSamplerCacheable, KSamplerAdvancedCacheable, ) +from .image_nodes import ImageCropByRatio from .komojini_nodes import * __all__ = [ @@ -19,4 +20,5 @@ __all__ = [ "FlowBuilderSetter", "CachedGetter", "DragNUWAImageCanvas", + "ImageCropByRatio", ] diff --git a/nodes/image_nodes.py b/nodes/image_nodes.py new file mode 100644 index 0000000..1880040 --- /dev/null +++ b/nodes/image_nodes.py @@ -0,0 +1,106 @@ +MAX_RESOLUTION = 8192 + + +class ImageCropByRatio: + @classmethod + def INPUT_TYPES(s): + return { + "required": { + "image": ("IMAGE",), + "width_ratio": ("INT", {"default": 1, "min": 1, "max": MAX_RESOLUTION}), + "height_ratio": ( + "INT", + {"default": 1, "min": 1, "max": MAX_RESOLUTION}, + ), + "position": ( + [ + "top-left", + "top-center", + "top-right", + "right-center", + "bottom-right", + "bottom-center", + "bottom-left", + "left-center", + "center", + ], + ), + "x_offset": ( + "INT", + { + "default": 0, + "min": -99999, + "step": 1, + }, + ), + "y_offset": ( + "INT", + { + "default": 0, + "min": -99999, + "step": 1, + }, + ), + } + } + + RETURN_TYPES = ( + "IMAGE", + "INT", + "INT", + ) + RETURN_NAMES = ( + "IMAGE", + "x", + "y", + ) + FUNCTION = "execute" + CATEGORY = "essentials" + + def execute(self, image, width_ratio, height_ratio, position, x_offset, y_offset): + _, oh, ow, _ = image.shape + + image_ratio = ow / oh + target_ratio = width_ratio / height_ratio + + if image_ratio > target_ratio: + height = oh + width = target_ratio * height + else: + width = ow + height = target_ratio * width + + if "center" in position: + x = round((ow - width) / 2) + y = round((oh - height) / 2) + if "top" in position: + y = 0 + if "bottom" in position: + y = oh - height + if "left" in position: + x = 0 + if "right" in position: + x = ow - width + + x += x_offset + y += y_offset + + x2 = x + width + y2 = y + height + + if x2 > ow: + x2 = ow + if x < 0: + x = 0 + if y2 > oh: + y2 = oh + if y < 0: + y = 0 + + image = image[:, y:y2, x:x2, :] + + return ( + image, + x, + y, + )