Files
EnragedAntelope c385f389ee v2.4.1: queue-time validation, absolute pixel ceiling, CI hardening
- Reject invalid configs in validate_inputs instead of mid-execution:
  Strict-mode multiple_of above max_res, out-of-range min_res/max_res/
  multiple_of, and unknown constraint modes
- Share the resolution and multiple_of bounds between define_schema() and
  validate_inputs() so the widget and the queue-time check cannot drift
- Cap the min-res pixel budget at an absolute 64 MP, floored at max_res
  squared; the multiplier alone permitted ~12 GB outputs at max_res=8192
- Warn on large upscales in Strict mode as well as min-res mode
- Pin GitHub Actions by commit SHA on node24-native majors; drop issues:write
  from the publish workflow and set contents:read on both
- Pin Comfy-Org/publish-node-action to the commit @v1 resolves to; the 1.0.1
  tag calls `comfy tracking disable`, removed from comfy-cli
- Add requirements-ci.txt with pip caching; add ruff config and a CI lint step
- Add schema-contract, tooltip, budget, crop-guard and validation tests
- Replace typing.Tuple with tuple
- Bump version to 2.4.1
2026-08-24 14:11:51 -04:00

90 lines
6.8 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# ComfyUI Constrain Resolution
A [ComfyUI](https://github.com/comfyanonymous/ComfyUI) node that resizes any image to fit your model's resolution rules: a minimum size, a maximum size, and dimensions guaranteed divisible by 2, 8, 16, 32, or 64. It keeps the aspect ratio by cropping a few pixels when needed, so the output is always exactly what strict image-to-image and image-to-video models expect.
![Example workflow: 1800×1013 input resized to 1280×720](docs/images/workflow.png)
In the example above, an 1800×1013 image becomes 1280×720 — within the 704–1280 limits, both dimensions divisible by 16, aspect ratio intact.
## Why
Many models fail or degrade when dimensions are wrong:
- Image-to-video models often require exact sizes with dimensions divisible by 8 or 16
- Diffusion models (Flux, SD, etc.) need dimensions divisible by at least 2, and some run faster at 32/64 alignment
- VRAM limits mean you need a hard cap on resolution
This node applies all three rules in one step and **guarantees divisibility on every output** — resize, round, and crop all land on multiples of your chosen number.
## Inputs
![Constrain Resolution node](docs/images/node.png)
| Input | Default | Purpose |
|---|---|---|
| `image` | — | Image (or batch) to resize |
| `min_res` | 704 | Neither dimension will end up below this |
| `max_res` | 1280 | Bounds the longest side. In the default mode the long side may exceed it on extreme aspect ratios — see constraint modes below |
| `multiple_of` | 2 | Output width and height are always divisible by this (1 disables) |
| `resize_method` | lanczos | Interpolation: `lanczos` (sharpest), `bicubic`, `bilinear`, `nearest-exact` (pixel art/masks), `area` (big downscales) |
| `constraint_mode` | Prioritize Min Resolution | What wins when an extreme aspect ratio can't satisfy both limits (see below) |
| `crop_as_required` | True | Crop minimally to hit exact dimensions instead of distorting the aspect ratio |
| `crop_position` | center | Which part to keep when cropping: center / top / bottom / left / right |
Every image is rescaled so its longest side lands on `max_res` — images already inside the range are resized too, not passed through. This is what makes the output size predictable for batching.
**Constraint modes** — with a very wide or very tall image, min and max can conflict:
- **Prioritize Min Resolution**: neither dimension goes below `min_res`, even if the long side must exceed `max_res`. Best default. At the default settings, beyond roughly a 52:1 aspect ratio the required output would be large enough to exhaust memory, so the node reports an error instead of trying — switch to Strict mode for those. The limit scales with `max_res` up to an absolute ceiling of 64 MP, and never refuses an output that fits inside your own `max_res × max_res` box.
- **Prioritize Max Resolution (Strict)**: output always fits in a `max_res × max_res` box (hard VRAM cap), even if the short side lands below `min_res`.
## Outputs
| Output | Description |
|---|---|
| `resized_image` | The constrained image — your main output |
| `original_image` | Untouched input passthrough |
| `width`, `height` | Final dimensions (handy for downstream nodes) |
| `final_aspect_ratio`, `original_aspect_ratio` | For monitoring how much the ratio changed |
## Quick recipes
- **Image-to-video prep**: `min_res=768, max_res=1024, multiple_of=16` — exact, divisible dimensions every time
- **Hard VRAM cap**: `max_res=1024, constraint_mode=Prioritize Max Resolution (Strict)`
- **Keep every pixel** (no cropping): `crop_as_required=False, multiple_of=1`
- **Headshots**: `crop_position=top` keeps faces when cropping portraits
## Installation
**ComfyUI Manager**: search for "Constrain Resolution" and install.
**Manual**:
```bash
cd ComfyUI/custom_nodes
git clone https://github.com/EnragedAntelope/ComfyUI-ConstrainResolution.git
```
Restart ComfyUI. No dependencies beyond ComfyUI itself (Python 3.10+).
## Notes
- Resizing uses ComfyUI's own resizer (`comfy.utils.common_upscale`), so results match core resize nodes; bicubic/lanczos output is clamped to the valid range to avoid overshoot artifacts.
- Divisibility, min/max, and crop dimensions are enforced together — the reported `width`/`height` always match the actual output tensor.
- Built on the ComfyUI v3 node API (`comfy_api.latest`).
- Impossible settings fail with a clear error rather than silently passing the image through — e.g. `multiple_of` larger than `max_res` in Strict mode, where no valid output size exists.
## Version history
- **v2.4.1**: Invalid settings are now rejected when the workflow is queued instead of mid-execution — `multiple_of` above `max_res` in Strict mode, plus out-of-range `min_res`/`max_res`/`multiple_of` and unknown constraint modes coming from hand-written API workflows, which the widget bounds alone no longer covered; the memory guard gained an absolute 64 MP ceiling, so it stays meaningful at large `max_res` instead of permitting multi-gigabyte outputs; large-upscale warnings now fire in Strict mode too, so tiny sources blown up 10x+ are no longer silent; CI hardening (GitHub Actions pinned by commit SHA, pip dependency caching, torch bounded to known-good majors); new tests keep the node schema in sync with `execute()` and enforce tooltips on every input
- **v2.4.0**: Refuse extreme-aspect-ratio upscales that would exhaust memory instead of attempting them (a 1×690 input at default settings previously asked for 704×485760, roughly 4 GB per batch item); fixed settings that silently passed the image through untouched (`multiple_of` above `max_res` in Strict mode, and thin strips at `multiple_of=1`); restored ComfyUI's built-in range and combo-option validation, which the previous `validate_inputs` signature disabled for every input; ~1.85× faster when cropping by dropping a resize whose result was discarded; crop decisions now use exact aspect ratios instead of 4-decimal rounded ones
- **v2.3.2**: Added CI test workflow (pytest on Python 3.10–3.12); warn on very large upscales in "Prioritize Min Resolution" mode; pass malformed zero-dimension inputs through unchanged instead of erroring
- **v2.3.1**: Rewrote README with current screenshots; enforce `min_res` even when rounding to a large `multiple_of` would dip below it
- **v2.3.0**: Added `resize_method` selection (lanczos default); fixed a rare off-by-one in cropped output size; removed unused numpy dependency; Python 3.10 compatibility; proper logging
- **v2.2**: Fixed strict max-resolution mode exceeding `max_res` after rounding; added test suite
- **v2.1.0**: Image resizing, smart cropping, crop position control, tooltips, input validation
- **v2.0.0**: Migrated to ComfyUI v3 specification
- **v1.1**: Initial release
## License
See [LICENSE](LICENSE). Issues and PRs welcome on [GitHub](https://github.com/EnragedAntelope/ComfyUI-ConstrainResolution/issues).