🐇 Batch Resize w/ Lanczos
Gamma-correct Lanczos on the GPU — resizing a whole batch in seconds
- image
- mask
- IMAGE
- width
- height
- mask
Resizing an image in ComfyUI is easy. Resizing a batch - 300 frames of video, say - is where the built-in options start to feel slow, because most of them fall back to CPU and Pillow, and Pillow's Lanczos is single-threaded molasses. Batch Resize w/ Lanczos exists for exactly that job: it runs the Lanczos resampler on the GPU via the pack's own TorchLanc library, and it does the resizing in linear light, which is the detail most resizers quietly skip.
Two things set it apart. First, speed: the author's own measurement is up to a 10× gain over Pillow on CPU, and the resampling weights get cached so the second run is even faster. Second, correctness: because it gamma-corrects (works in linear color space before resampling), it avoids the subtle darkening and halo artifacts you get when you Lanczos a non-linearly-encoded image directly - the kind of thing you only notice after you've rendered 500 frames and compared them side by side. The node's UI is modeled on Kijai's popular resize nodes, so if you've used those, the layout will feel familiar.
How it works
Lanczos is a windowed-sinc interpolation - high quality, sharp, but expensive, which is why it's usually the CPU bottleneck. WhiteRabbit implements it as a CUDA kernel (TorchLanc) and processes the whole batch in one pass. The gamma correction step converts to linear light, resamples, and converts back, which is why gradients come out clean.
The modes that matter
- Keep AR - fit inside width×height, preserving aspect. The default and the safe choice.
- Stretch - force to width×height. Distorts. Only for when you know what you're doing.
- Crop (Cover + Crop) - scale to cover, then crop to the target. Great for making a uniform thumbnail strip from mixed-aspect frames.
- Pad (Fit + Pad) - fit inside, pad the rest with
pad_color. - AR Scale + Divisible Crop - the video-diffusion special: scale by the source's long side to a divisible target and crop only the short side, so you get an output that's clean for video models.
divisible_by is the hidden gem for anyone feeding a video model - it forces output dimensions to multiples of N (16 or 8), which the built-in resizers often make you do by hand. max_batch_size chunks the batch for VRAM control, sinc_window (default 3) trades sharpness against ringing, and crop_position picks which edges survive. There's also an optional mask input that follows the same crop/pad as the image, resized with nearest-neighbor so your mask stays hard-edged - useful if you're resizing a mask alongside the frames.
Outputs
- IMAGE - the resized batch.
- width / height (INT) - the actual output dimensions, which drift from the request when
divisible_byor AR modes adjust things. Wire these out if a downstream node needs to know the true size. - mask - the resized mask, if you gave one.
Installing it
This node is the reason the pack has a pip requirement at all:
cd ComfyUI/custom_nodes
git clone https://github.com/Artificial-Sweetener/comfyui-WhiteRabbit
cd comfyui-WhiteRabbit
python -m pip install -r requirements.txt # installs torchlanc>=1.1.0
Or ComfyUI Manager → "WhiteRabbit". TorchLanc is a CUDA extension, so if you're on a CPU-only box, expect this one to complain - the GPU is the whole point.
Where people get burned
- Expecting a generative upscaler. It isn't. This adds no detail - it resizes. If you want more pixels and more detail, pair it with an ESRGAN upscale (see Upscale w/ Model (Advanced)) rather than expecting Lanczos to invent content. The KB frames this as the "more pixels" job versus the "more detail" job, and they're different tools.
precision= fp16 with a picky eye. fp16/bf16 are faster but can visibly soften gradients; keep fp32 for final renders and use the low-precision modes for previews.- Turning
sinc_windowway up. a=8 is very sharp but rings badly on edges. Stick near the default.
It's the resizer I'd reach for on any batch job where quality and speed both matter. The gamma correction alone is worth the install.
Inputs (11)
| Name | Type | Default | Description |
|---|---|---|---|
| image | IMAGE | Input batch (B,H,W,C) in [0,1] float. Processed on GPU. | |
| width | INT | 10241–16384 | Target width (pixels). Notes: • Keep AR / Pad: maximum width for the fit • Crop: final output width • AR Scale + Divisible Crop: requested width before divisibility |
| height | INT | 5761–16384 | Target height (pixels). Notes: • Keep AR / Pad: maximum height for the fit • Crop: final output height • AR Scale + Divisible Crop: requested height before divisibility |
| resize_mode | COMBO | Keep AR | Modes: - Keep AR: Fit inside width×height (preserve aspect) - Stretch: Force to width×height (may distort) - Crop (Cover + Crop): Scale to cover, then crop to width×height - Pad (Fit + Pad): Fit inside, then pad to width×height - AR Scale + Divisible Crop: Scale by SOURCE long side to ≤ requested divisible; crop ONLY the short side to its divisible |
| divisible_by | INT | 11–4096 | Force output dimensions to multiples of N. Details: • Keep AR: Fit → then step down to the largest size ≤ requested that keeps AR AND makes both sides divisible • AR Scale + Divisible Crop: Lock the scaled LONG side to its divisible target; crop ONLY the short side to its divisible Set to 1 (or 0 in UI) to disable |
| max_batch_size | INT | 00–4096 | 0 = process whole batch >0 = chunk the batch to this size |
| sinc_window | INT | 31–8 | Lanczos window size (a). Higher = sharper (more ringing). |
| pad_color | STRING | 0, 0, 0 | Pad mode only. RGB as 'r, g, b' (0-255). |
| crop_position | COMBO | center | Where to crop/pad from. Choose which edges are preserved for cropping, or where padding is added. |
| precision | COMBO | fp32 | Resampling compute dtype. |
| maskopt | MASK | Optional mask (B,H,W) in [0,1]. Resized with nearest. Follows the same crop/pad as the image. |
Outputs (4)
| Name | Type | Description |
|---|---|---|
| IMAGE | IMAGE | — |
| width | INT | — |
| height | INT | — |
| mask | MASK | — |