Pepe Scale Image By
Photoshop's Bicubic Sharper, reverse-engineered into a ComfyUI node
- image
- image
- width
- height
Downscaling is where ComfyUI's resamplers embarrass themselves. If you've ever shrunk clean line art or a flat-color illustration and watched bilinear turn it to mush or Lanczos halo every edge, you know the feeling - there's a well-worn r/comfyui thread about exactly this, and the honest takeaway is that Comfy's built-in options don't nail the downscale the way Photoshop does. Pepe Scale Image By is an attempt to fix that: it's a NumPy resampler that approximates Photoshop's Bicubic Sharper interpolation, based on Jason Summers' ResampleScope notes.
It's a niche node, but it's a good niche. If you spend your life downscaling clean vector-ish images or prepping anime frames before feeding a video model, this is the resampler that doesn't betray you.
How it works
The math is the interesting part, and it's refreshingly documented in the README. For each axis the node runs an integrated box prepass when the scale drops below 0.25 (a large downscale), then a cubic pass with B = 0, blur = 1.05, and a scale-dependent C - that's the classic Mitchell-Netravali-family parameterization Photoshop's bicubic variants use, and the B=0 value is what gives it the "sharper" character. It processes X first, then Y. When clamp_intermediate is on (it is by default), values are clamped after each cubic pass to avoid overshoot building up between axes.
Two honest caveats straight from the author: it is not guaranteed pixel-identical to Photoshop - boundary handling, rounding and clamping are reverse-engineered approximations - and it runs on CPU via NumPy, so big images or batches scale slower than ComfyUI's GPU path. Manual ring-pattern tests reportedly match Photoshop closely from a 0.3 scale upward; below 0.25 there are minor differences around the box prepass. For most real downscales, that's good enough to see the quality difference immediately.
The inputs that matter
scale_by- the factor, 0.01 to 16. The star of the show; this is where "scale by 0.5" lives.snap_to_stride(bool) andstride(default 8) - snap the output dimensions to a stride so they stay latent/VAE-friendly. Thesnap_mode(nearest/down/up) picks whether snapping rounds, floors, or ceils.clamp_intermediate(default on) - keep the intermediate pass clamped. Leave it on unless you're chasing a specific look and know why.
Outputs are image, plus width and height as INTs you can wire into an Empty Latent Image or a resize node downstream.
Installing it
Pepe Scale Image By ships in Pepehoschi/ComfyUI-PepeUtils (GPL-3.0). Install via ComfyUI Manager (search "ComfyUI-PepeUtils") or:
cd ComfyUI/custom_nodes
git clone https://github.com/Pepehoschi/ComfyUI-PepeUtils
Restart ComfyUI. No extra dependencies - torch, numpy and Pillow, all already in ComfyUI.
When to reach for it (and when not to)
Reach for it when quality-of-downscale matters: shrinking a high-res render before it goes into a video or img2img pass, prepping line art, making clean thumbs. Skip it when you're enlarging - this is a downscale-sharpened resampler, and for pure upscaling you usually want a real upscaler or plain Lanczos (its sibling Pepe Resize Image auto-picks Lanczos for growth for exactly that reason). And skip it for bulk batches where CPU speed matters more than the last bit of edge quality. In short: when the pixels matter, this is the one you reach for; when throughput matters, use the fast path.
Inputs (6)
| Name | Type | Default | Description |
|---|---|---|---|
| image | IMAGE | — | |
| scale_by | FLOAT | 0.500.01–16 | — |
| snap_to_stride | BOOLEAN | false | — |
| stride | INT | 81–1024 | — |
| snap_mode | COMBO | nearest | 3 options: nearest, down, up |
| clamp_intermediate | BOOLEAN | true | — |
Outputs (3)
| Name | Type | Description |
|---|---|---|
| image | IMAGE | — |
| width | INT | — |
| height | INT | — |