Focal Rescale Rel
Focal cropping in fractions, not pixels
- image_in
- IMAGE
- rect_left
- rect_top
- rect_width
- rect_height
Focal Rescale Rel is the more flexible sibling of Focal Rescale. Same idea - crop around a point you care about, then scale to a target size without distortion - but where the original takes its focal point in source-image pixels, this one works in fractions. The focal point is a proportion of the image, and the crop size is a proportion of the image. If you've ever wired a hardcoded coordinate into a node and had it go stale the moment the source image changed, you'll feel the difference immediately.
How it works
focal_x and focal_y run 0 to 1 - (0,0) is top-left, (1,1) bottom-right, and 0.5, 0.5 is dead center. coverage (also 0 to 1) sets how big the crop window is: it's a fraction of the smaller dimension of the source, stretched to your target aspect ratio. So coverage of 0.5 on a 1024-tall image gives you a roughly 512-tall crop window. The window gets centered on the focal point, cropped, and resized to your width/height.
The one input that trips people up is fit_inside. When true, the crop window is clamped so it stays entirely inside the image - the same behavior Focal Rescale does automatically. When false, and your focal point sits near an edge, the window can poke outside the image, and PIL pads the out-of-bounds area with black. That's rarely what you want, so leave it on unless you're deliberately courting black bars.
Inputs and outputs
The essentials: width / height (output canvas, 16–2048), focal_x / focal_y (0–1, default center), coverage (0–1, default 0.5), and fit_inside (default off - turn it on). Outputs are the cropped IMAGE plus rect_left / rect_top / rect_width / rect_height in source pixels, same as its sibling - handy for mirroring the exact crop onto a mask or depth map.
Why pick this over Focal Rescale
Relative coordinates don't break when the input changes. If your workflow is batch-driven, or the focal point is computed elsewhere rather than hand-placed, fractions survive a resize while absolute pixels don't. That's also why the pack's Mask to Crop node uses this node's logic under the hood - a mask naturally gives you a center and an extent, both expressible as fractions without ever knowing the image's pixel size. The trade is one extra knob to understand: coverage, which is really just "how much of the source do you want to keep."
Gotchas
Same single-image caveat as the rest of the pack's crop nodes - the multi-image path here isn't worth trusting, so process one image at a time. And if you crank coverage near 1 on a portrait source with a landscape target, the window can't span the whole image, so you'll crop tighter than you meant to. That's coverage doing its job, not a bug - dial it down and the crop loosens.
Installing it
No dependencies beyond ComfyUI's own image libraries - pure PIL math, nothing to download. ComfyUI Manager: search for Comfy_Felsirnodes (or "Felsir"), install, restart. Manual: cd ComfyUI/custom_nodes and git clone https://github.com/Felsir/Comfy_Felsirnodes, restart. It's under Add Node → Felsir.
Inputs (7)
| Name | Type | Default | Description |
|---|---|---|---|
| image_in | IMAGE | — | |
| width | INT | 51216–2048 | — |
| height | INT | 51216–2048 | — |
| focal_x | FLOAT | 0.500–1 | — |
| focal_y | FLOAT | 0.500–1 | — |
| coverage | FLOAT | 0.500–1 | — |
| fit_inside | BOOLEAN | false | — |
Outputs (5)
| Name | Type | Description |
|---|---|---|
| IMAGE | IMAGE | — |
| rect_left | INT | — |
| rect_top | INT | — |
| rect_width | INT | — |
| rect_height | INT | — |