Support transmitting partial tiles/crops of the canvas in Krita workflows

This commit is contained in:
Acly
2025-12-30 23:47:29 +01:00
parent ad320a218c
commit 79e9b6426f
+39 -4
View File
@@ -90,9 +90,11 @@ class KritaOutput(io.ComfyNode):
category="krita",
inputs=[
io.Image.Input("images"),
io.Int.Input("x", "offset x", default=0),
io.Int.Input("y", "offset y", default=0),
io.String.Input("name", default=""),
io.Combo.Input(
"batch_mode", OutputBatchMode, "batch_mode", default=OutputBatchMode.default
"batch_mode", OutputBatchMode, "batch mode", default=OutputBatchMode.default
),
io.Boolean.Input("resize_canvas", "resize canvas", default=False),
],
@@ -103,6 +105,8 @@ class KritaOutput(io.ComfyNode):
def execute(
cls,
images: torch.Tensor,
x: int = 0,
y: int = 0,
name="",
batch_mode: OutputBatchMode | str = OutputBatchMode.default,
resize_canvas=False,
@@ -110,6 +114,8 @@ class KritaOutput(io.ComfyNode):
batch_mode = batch_mode.value if isinstance(batch_mode, OutputBatchMode) else batch_mode
info = {
"name": name,
"offset_x": x,
"offset_y": y,
"batch_mode": batch_mode,
"resize_canvas": resize_canvas,
}
@@ -171,6 +177,21 @@ class KritaCanvas(io.ComfyNode):
return io.NodeOutput(_placeholder_image(), 512, 512, 0)
class SelectionContext(Enum):
automatic = "automatic"
entire_image = "entire image"
mask_bounds = "mask bounds"
_selection_context_help = """
Determines the section (crop bounding box) of the image and mask to transmit:
- automatic: area around the selection determined by Krita settings
- entire image: always use the entire canvas area
- mask bounds: tight bounding box of the current selection
This affects the Selection and Canvas nodes. The offset x/y outputs indicate the top-left corner of the context area relative to the full canvas."""
class KritaSelection(io.ComfyNode):
@classmethod
def define_schema(cls):
@@ -178,12 +199,26 @@ class KritaSelection(io.ComfyNode):
node_id="ETN_KritaSelection",
display_name="Krita Selection",
category="krita",
outputs=[io.Mask.Output(display_name="mask"), io.Boolean.Output(display_name="active")],
inputs=[
io.Combo.Input(
"context",
options=SelectionContext,
default=SelectionContext.entire_image,
tooltip=_selection_context_help,
),
io.Int.Input("padding", "padding", default=0, min=0),
],
outputs=[
io.Mask.Output("mask", "mask"),
io.Boolean.Output("active", "active"),
io.Int.Output("x", "offset x"),
io.Int.Output("y", "offset y"),
],
)
@classmethod
def execute(cls):
return io.NodeOutput(torch.ones(1, 512, 512), False)
def execute(cls, **kwargs):
return io.NodeOutput(torch.ones(1, 512, 512), False, 0, 0)
class KritaImageLayer(io.ComfyNode):