Nodes/KJNodes for ComfyUI/Image Transform KJ
ComfyUI Node Runs on cloud

Image Transform KJ

Crop, resize, pad, and rotate on one interactive canvas

By kijai·Created 3 years ago·Updated 2 days ago· 3,030
Image Transform KJ
  • image
  • mask
  • output
  • output_mask
  • bbox
  • bbox_mask
  • width
  • height
target_width0
target_height0
upscale_methodlanczos
keep_proportion
divisible_by2
extra_padding
invert_crop
bboxes

Most image workflows end up with a chain of separate crop, resize, pad, and rotate nodes stacked one after another, each with its own numeric widgets you're nudging blind. Image Transform KJ replaces that chain with one node and a live canvas: connect an image, a preview appears right there in the node, and you draw your crop, drag to reposition, and rotate by eye instead of by trial-and-error numbers.

How it works

Once an image is connected, the preview shows up automatically inside the node. From there it's direct manipulation, not widgets:

  • Cropping - click and drag to draw a crop region. Drag inside the region to move it, drag an edge or corner to resize it. Right-click a region to delete it. Hold Ctrl while dragging to snap to a grid, Shift while resizing to constrain aspect ratio, and Alt while resizing to resize symmetrically from the center.
  • Padding - hold Shift and drag to adjust where the padding sits relative to your crop.
  • Rotation - a rotate button turns on a rotation cross you drag to spin the image; right-click it to reset back to zero.

Underneath the interaction, target_width/target_height (0 = keep the original size) control the final output resolution, keep_proportion decides how the source fits into that target (crop-to-fill vs. pad-to-fit vs. stretch, depending on what your build exposes), and extra_padding adds padding filled with either a flat color or an edge-extension mode (clamp, repeat, or mirror) rather than leaving it blank.

The inputs and outputs that matter

  • image in (accepts a flexible image-type input, so it plays nicely with different image/list shapes elsewhere in the graph) - the source you're transforming, optionally paired with an optional mask input if you're transforming a masked region alongside the image.
  • target_width / target_height (0 = keep original) - your desired output dimensions.
  • upscale_method (default lanczos) - the resize algorithm when scaling is involved.
  • divisible_by (default 2) - rounds output dimensions to a multiple of this value, which matters a lot for video and diffusion models that require dimensions divisible by 8, 16, or 32; set it to whatever your downstream model actually needs.
  • bboxes (STRING) - lets you pass crop-region coordinates as text instead of drawing them by hand, useful once you've got a region dialed in and want to reuse or automate it.

Outputs come back as lists, which matches the fact that you can draw more than one crop region on the canvas: output (the transformed image(s)), output_mask, bbox (the raw crop-region coordinates), bbox_mask, plus scalar width and height for the final dimensions.

Installing it

Ships with the pack:

  • ComfyUI Manager - search KJNodes for ComfyUI, install, restart.
  • Manual - cd ComfyUI/custom_nodes && git clone https://github.com/kijai/ComfyUI-KJNodes, then pip install -r ComfyUI-KJNodes/requirements.txt, restart.

The interactive canvas is a JS-side feature of the pack, so make sure your browser cache isn't serving a stale copy of the extension after an update - a hard refresh of the ComfyUI tab fixes more "the node looks wrong" reports than you'd expect with any interactive custom node.

Common issues & troubleshooting

Output size isn't what I expected. Check divisible_by first - it silently rounds your final dimensions, so a target_width of 1000 with divisible_by at 2 might not land exactly where you think once padding and proportion rules are applied on top.

Multiple crops came out as a batch when I only wanted one. That's expected once you understand the output is list-typed: every crop region you draw on the canvas produces an entry in output. If you only drew one region, you'll get one item - if a downstream node is complaining about batch size, check how many regions are actually on the canvas.

Can't tell what changed after clicking around the canvas. The interaction set is dense (Ctrl, Shift, Alt each do something different depending on whether you're cropping or resizing), and it's easy to trigger a mode you didn't mean to. Right-click resets a region or the rotation cross - that's the fastest way back to a known state if you've lost track of what you did.

CategoryKJNodes/image

Inputs (10)

NameTypeDefaultDescription
imageCOMFY_MATCHTYPE_V3The image or mask to transform.
target_widthINT00–16384Target output width. 0 = keep original dimensions.
target_heightINT00–16384Target output height. 0 = keep original dimensions.
upscale_methodCOMBOlanczosInterpolation method for resizing.
keep_proportionCOMBO8 options: [object Object], [object Object], [object Object], [object Object], [object Object], [object Object], +2
divisible_byINT20–512
extra_paddingCOMBO5 options: [object Object], [object Object], [object Object], [object Object], [object Object]
invert_cropCOMBO2 options: [object Object], [object Object]
bboxesSTRING
maskoptMASKOptional mask to transform alongside the image.

Outputs (6)

NameTypeDescription
outputCOMFY_MATCHTYPE_V3
output_maskMASK
bboxBBOX
bbox_maskMASK
widthINTWidth of the output image.
heightINTHeight of the output image.