Skip to content

Commit da54620

Browse files
committed
image crop widget
1 parent c543ad8 commit da54620

File tree

2 files changed

+24
-5
lines changed

2 files changed

+24
-5
lines changed

comfy_api/latest/_io.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1125,6 +1125,22 @@ def __init__(self, id: str, display_name: str=None, optional=False, tooltip: str
11251125
def as_dict(self):
11261126
return super().as_dict()
11271127

1128+
@comfytype(io_type="IMAGECROP")
1129+
class ImageCrop(ComfyTypeI):
1130+
"""Widget for visual image cropping with x, y, width, height controls."""
1131+
Type = dict
1132+
1133+
class Input(WidgetInput):
1134+
def __init__(self, id: str, display_name: str=None, optional=False, tooltip: str=None,
1135+
socketless: bool=True,
1136+
default: dict=None):
1137+
super().__init__(id, display_name, optional, tooltip, None, default, socketless)
1138+
if default is None:
1139+
self.default = {"x": 0, "y": 0, "width": 512, "height": 512}
1140+
1141+
def as_dict(self):
1142+
return super().as_dict()
1143+
11281144
DYNAMIC_INPUT_LOOKUP: dict[str, Callable[[dict[str, Any], dict[str, Any], tuple[str, dict[str, Any]], str, list[str] | None], None]] = {}
11291145
def register_dynamic_input_func(io_type: str, func: Callable[[dict[str, Any], dict[str, Any], tuple[str, dict[str, Any]], str, list[str] | None], None]):
11301146
DYNAMIC_INPUT_LOOKUP[io_type] = func
@@ -1971,4 +1987,5 @@ def as_dict(self) -> dict:
19711987
"add_to_dict_v3",
19721988
"V3Data",
19731989
"ImageCompare",
1990+
"ImageCrop",
19741991
]

comfy_extras/nodes_images.py

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,16 +26,18 @@ def define_schema(cls):
2626
category="image/transform",
2727
inputs=[
2828
IO.Image.Input("image"),
29-
IO.Int.Input("width", default=512, min=1, max=nodes.MAX_RESOLUTION, step=1),
30-
IO.Int.Input("height", default=512, min=1, max=nodes.MAX_RESOLUTION, step=1),
31-
IO.Int.Input("x", default=0, min=0, max=nodes.MAX_RESOLUTION, step=1),
32-
IO.Int.Input("y", default=0, min=0, max=nodes.MAX_RESOLUTION, step=1),
29+
IO.ImageCrop.Input("crop_region"),
3330
],
3431
outputs=[IO.Image.Output()],
3532
)
3633

3734
@classmethod
38-
def execute(cls, image, width, height, x, y) -> IO.NodeOutput:
35+
def execute(cls, image, crop_region) -> IO.NodeOutput:
36+
x = crop_region.get("x", 0)
37+
y = crop_region.get("y", 0)
38+
width = crop_region.get("width", 512)
39+
height = crop_region.get("height", 512)
40+
3941
x = min(x, image.shape[2] - 1)
4042
y = min(y, image.shape[1] - 1)
4143
to_x = width + x

0 commit comments

Comments
 (0)