Resize Modes
“Resize” sounds like one operation. It’s actually a family of about two dozen distinct operations, each producing a different result for the same input. This page is a vendor-neutral catalogue of every meaningful way to resize an image, organised by intent — no library names, no provider tokens, no API. It’s the conceptual map; for the Chainsaw methods that implement these, see Resize & Fit.
Each operation includes two reference tables — how the major image CDNs and the major PHP image libraries (including Chainsaw) name the same operation. ❌ means the operation is not natively supported by that backend; 🟡 means partial / emulated support.
At a glance
The four ops below all take the same source (a 4 × 3 landscape) and the same target box (a 1 × 1 square, dotted outline) — and produce four visibly different results. This is the cluster users get most confused about.
Family 1 — Pure scaling
Multiply the source uniformly. No reframing, no cropping, no padding — just resample.
Scale by factor
Multiply both dimensions by the same number. A factor of 0.5 halves the image; 2 doubles it.
Output: source × factor · Aspect: preserved · Upscale: allowed when factor > 1
| CDN | API |
|---|---|
| Cloudflare | ❌ |
| Cloudinary | w_0.5 (fractional value) |
| Imagor | ❌ |
| imgix | ❌ |
| imgproxy | ❌ |
| Intervention | ❌ |
| Thumbor | ❌ |
| wsrv.nl | ❌ |
| PHP library | API |
|---|---|
| Chainsaw | scale(0.5) |
| Glide | ❌ |
| Imagine | resize($size->scale(0.5)) |
| JoliCode | resize: { width: 50%, height: 50% } |
| Liip | scale: { to: 0.5 } |
| Spatie | ❌ |
| TYPO3 MP | ❌ |
Scale to a target width
Pick a width; the height follows from the source’s aspect ratio.
Output: width = N, height = source-derived · Aspect: preserved · Upscale: allowed
| CDN | API |
|---|---|
| Cloudflare | width=N |
| Cloudinary | w_N |
| Imagor | Nx0 |
| imgix | w=N |
| imgproxy | w:N |
| Intervention | scale(width: N) |
| Thumbor | Nx0 |
| wsrv.nl | w=N |
| PHP library | API |
|---|---|
| Chainsaw | width(N) |
| Glide | w=N |
| Imagine | resize($size->widen(N)) |
| JoliCode | widen: { width: N } |
| Liip | relative_resize: { widen: N } |
| Spatie | width(N) |
| TYPO3 MP | setWidth(N) |
Scale to a target height
The mirror of the above, with height as the controlling dimension.
Output: height = N, width = source-derived · Aspect: preserved · Upscale: allowed
| CDN | API |
|---|---|
| Cloudflare | height=N |
| Cloudinary | h_N |
| Imagor | 0xN |
| imgix | h=N |
| imgproxy | h:N |
| Intervention | scale(height: N) |
| Thumbor | 0xN |
| wsrv.nl | h=N |
| PHP library | API |
|---|---|
| Chainsaw | height(N) |
| Glide | h=N |
| Imagine | resize($size->heighten(N)) |
| JoliCode | heighten: { height: N } |
| Liip | relative_resize: { heighten: N } |
| Spatie | height(N) |
| TYPO3 MP | setHeight(N) |
Family 2 — Fit inside a target box
Place the source inside a target rectangle, preserving aspect ratio, with the output never exceeding the box on at least one axis. The output size depends on the source’s aspect.
Fit inside
Shrink the source until it fits entirely within the box. The output’s aspect matches the source, so it may be smaller than the box on one axis.
Output: ≤ box on each axis · Aspect: preserved · Upscale: allowed
| CDN | API |
|---|---|
| Cloudflare | fit=contain |
| Cloudinary | c_fit |
| Imagor | fit-in/WxH + filters:upscale() |
| imgix | fit=clip |
| imgproxy | rs:fit:W:H + el:1 |
| Intervention | scale(W, H) |
| Thumbor | fit-in/WxH + filters:upscale() |
| wsrv.nl | fit=inside |
| PHP library | API |
|---|---|
| Chainsaw | contain(W, H) |
| Glide | w=W&h=H&fit=contain |
| Imagine | thumbnail(new Box(W, H), THUMBNAIL_INSET | THUMBNAIL_FLAG_UPSCALE) |
| JoliCode | resize: { width: W, height: H, mode: inside } |
| Liip | thumbnail: { size: [W, H], mode: inset, allow_upscale: true } |
| Spatie | fit(Fit::Contain, W, H) |
| TYPO3 MP | setWidth("Wm") + setHeight("Hm") (suffix m) |
Fit inside, no upscale
Same as fit inside, but never enlarges. If the source is already smaller than the box, the output equals the source.
Output: ≤ box and ≤ source on each axis · Aspect: preserved · Upscale: forbidden
| CDN | API |
|---|---|
| Cloudflare | fit=scale-down |
| Cloudinary | c_limit |
| Imagor | fit-in/WxH + filters:no_upscale() |
| imgix | fit=max |
| imgproxy | rs:fit:W:H (default el:0) |
| Intervention | scaleDown(W, H) |
| Thumbor | fit-in/WxH + filters:no_upscale() |
| wsrv.nl | fit=inside&we |
| PHP library | API |
|---|---|
| Chainsaw | contain(W, H, noUpscale: true) |
| Glide | w=W&h=H&fit=max |
| Imagine | thumbnail(new Box(W, H), THUMBNAIL_INSET) |
| JoliCode | resize: { width: W, height: H, mode: inside, allow_upscale: false } |
| Liip | downscale: { max: [W, H] } |
| Spatie | fit(Fit::Max, W, H) |
| TYPO3 MP | ❌ |
Fit inside, only upscale
The opposite cap: never shrinks. The output is at least as large as the box on at least one axis, growing the source if necessary.
Output: ≥ box on at least one axis · Aspect: preserved · Upscale: required when source < box
| CDN | API |
|---|---|
| Cloudflare | ❌ |
| Cloudinary | c_mfit / c_mpad |
| Imagor | ❌ |
| imgix | ❌ |
| imgproxy | ❌ |
| Intervention | ❌ |
| Thumbor | ❌ |
| wsrv.nl | fit=outside |
| PHP library | API |
|---|---|
| Chainsaw | ❌ (deferred) |
| Glide | ❌ |
| Imagine | ❌ |
| JoliCode | resize: { width: W, height: H, mode: inside, allow_downscale: false } |
| Liip | upscale: { min: [W, H] } |
| Spatie | ❌ |
| TYPO3 MP | ❌ |
Family 3 — Fill a target box exactly
Force the output dimensions to match the target box exactly. The five ops below differ in how they reconcile the source’s aspect with the box.
Stretch
Force the output to match the box exactly, distorting the source. Aspect ratio is discarded — circles become ovals.
Output: = box · Aspect: dropped · Upscale: allowed
| CDN | API |
|---|---|
| Cloudflare | fit=squeeze |
| Cloudinary | c_scale |
| Imagor | stretch/WxH |
| imgix | fit=scale |
| imgproxy | rs:force:W:H |
| Intervention | resize(W, H) |
| Thumbor | WxH + filters:stretch() |
| wsrv.nl | fit=fill |
| PHP library | API |
|---|---|
| Chainsaw | stretch(W, H) |
| Glide | w=W&h=H&fit=stretch |
| Imagine | resize(new Box(W, H)) |
| JoliCode | resize: { width: W, height: H, mode: exact } |
| Liip | resize: { size: [W, H] } |
| Spatie | fit(Fit::Stretch, W, H) |
| TYPO3 MP | setWidth(W) + setHeight(H) (no suffix) |
Pad to fit
Shrink the source to fit inside the box (preserving aspect), then fill the empty area on the short axis with a background colour. The output is partly source pixels, partly fill.
Output: = box · Aspect: preserved · Upscale: allowed
| CDN | API |
|---|---|
| Cloudflare | fit=pad |
| Cloudinary | c_pad |
| Imagor | fit-in/WxH + filters:fill(RGB) |
| imgix | fit=fill&fill=solid&fill-color=fff |
| imgproxy | rs:fit:W:H/ex:1/bg:RGB |
| Intervention | contain(W, H, bg) |
| Thumbor | fit-in/WxH + filters:fill(RGB) |
| wsrv.nl | fit=contain&cbg=fff |
| PHP library | API |
|---|---|
| Chainsaw | pad(W, H, '#fff') |
| Glide | w=W&h=H&fit=fill-max&bg=fff |
| Imagine | composed: Canvas + thumbnail(INSET) |
| JoliCode | resize: mode: inside then expand: { background_color: '#fff' } |
| Liip | thumbnail: mode: inset then background: { color: '#fff' } |
| Spatie | fit(Fit::FillMax, W, H, backgroundColor: '#fff') |
| TYPO3 MP | ❌ |
Pad to fit, no upscale
Same as pad to fit, but capped at source dims. Sources smaller than the box are padded around at native size rather than enlarged first.
Output: = box · Aspect: preserved · Upscale: forbidden
| CDN | API |
|---|---|
| Cloudflare | ❌ |
| Cloudinary | c_lpad |
| Imagor | fit-in/WxH + filters:fill(RGB) + filters:no_upscale() |
| imgix | fit=fillmax |
| imgproxy | rs:fit:W:H/ex:1/el:0/bg:RGB |
| Intervention | containDown(W, H, bg) |
| Thumbor | fit-in/WxH + filters:fill(RGB) + filters:no_upscale() |
| wsrv.nl | 🟡 (fit=contain&we&cbg=fff) |
| PHP library | API |
|---|---|
| Chainsaw | pad(W, H, '#fff', noUpscale: true) |
| Glide | w=W&h=H&fit=fill&bg=fff |
| Imagine | composed: Canvas + thumbnail(INSET) |
| JoliCode | expand: { background_color: '#fff' } (no-ops if target < source) |
| Liip | downscale + background (composed) |
| Spatie | fit(Fit::Fill, W, H, backgroundColor: '#fff') |
| TYPO3 MP | ❌ |
Cover
Scale the source so it covers the entire box, preserving aspect, then crop the overflow on the long axis. The output is fully composed of source pixels — no fill colour.
Where the overflow is cropped from is configurable — the same anchor vocabulary as Family 4 applies: centre (default), one of eight compass positions (top, bottom, left, right, top-left, …), a focal point, or smart / saliency / face detection.
Output: = box · Aspect: preserved · Upscale: allowed · Anchor: centre / compass / focal / smart
| CDN | API |
|---|---|
| Cloudflare | fit=cover |
| Cloudinary | c_fill |
| Imagor | WxH + halign/valign |
| imgix | fit=crop |
| imgproxy | rs:fill:W:H |
| Intervention | cover(W, H) |
| Thumbor | WxH + halign/valign |
| wsrv.nl | fit=cover |
| PHP library | API |
|---|---|
| Chainsaw | cover(W, H) (or crop(W, H) alias) |
| Glide | w=W&h=H&fit=crop |
| Imagine | thumbnail(new Box(W, H), THUMBNAIL_OUTBOUND | THUMBNAIL_FLAG_UPSCALE) |
| JoliCode | thumbnail: { width: W, height: H } |
| Liip | thumbnail: { size: [W, H], mode: outbound, allow_upscale: true } |
| Spatie | fit(Fit::Crop, W, H) |
| TYPO3 MP | setWidth("Wc") + setHeight("Hc") (suffix c) |
Cover, no upscale
Same as cover, but never enlarges. If the source is smaller than the box, the output stays at source dims (no upscale, no padding). When cover does apply, the overflow anchor is the same as Cover above.
Output: ≤ box, ≤ source · Aspect: preserved · Upscale: forbidden · Anchor: centre / compass / focal / smart
| CDN | API |
|---|---|
| Cloudflare | fit=crop |
| Cloudinary | c_lfill |
| Imagor | 🟡 (composed) |
| imgix | fit=min |
| imgproxy | rs:fill-down:W:H |
| Intervention | coverDown(W, H) |
| Thumbor | 🟡 (composed) |
| wsrv.nl | 🟡 (fit=cover&we) |
| PHP library | API |
|---|---|
| Chainsaw | cover(W, H, noUpscale: true) |
| Glide | ❌ |
| Imagine | thumbnail(new Box(W, H), THUMBNAIL_OUTBOUND) |
| JoliCode | thumbnail: { width: W, height: H, allow_upscale: false } |
| Liip | thumbnail: { size: [W, H], mode: outbound } |
| Spatie | ❌ |
| TYPO3 MP | ❌ |
Family 4 — Region selection
Cut a rectangle out of the source. The defining choice is where the rectangle sits.
Centre crop to dimensions
Cut a rectangle of the requested size from the centre of the source. Pixels outside the rectangle are discarded.
| CDN | API |
|---|---|
| Cloudflare | fit=cover (no gravity = centre) |
| Cloudinary | c_fill,g_center |
| Imagor | WxH (default centre) |
| imgix | fit=crop&crop=center |
| imgproxy | rs:fill:W:H&g:ce |
| Intervention | cover(W, H, "center") |
| Thumbor | WxH/center/middle |
| wsrv.nl | fit=cover&a=center |
| PHP library | API |
|---|---|
| Chainsaw | cover(W, H) (default centre) |
| Glide | w=W&h=H&fit=crop (default centre) |
| Imagine | crop(new Point($x, $y), new Box(W, H)) (caller computes centre offset) |
| JoliCode | thumbnail: { width: W, height: H, crop_position: center } |
| Liip | fixed: { width: W, height: H } |
| Spatie | crop(W, H, CropPosition::Center) |
| TYPO3 MP | ❌ |
Compass-anchored crop
Same as centre crop, but anchored to one of eight compass directions instead of the centre: top-left, top, top-right, left, right, bottom-left, bottom, bottom-right. The anchor decides which edge survives and which is cropped away.
| CDN | API |
|---|---|
| Cloudflare | gravity=top (no corner keywords — corners map to coordinates: gravity=0x0) |
| Cloudinary | g_north_west (compass set) |
| Imagor | halign + valign segments |
| imgix | crop=top,left |
| imgproxy | g:nowe (compass set: no/so/ea/we/noea/nowe/...) |
| Intervention | cover(W, H, "top-left") |
| Thumbor | halign + valign segments |
| wsrv.nl | a=top-left |
| PHP library | API |
|---|---|
| Chainsaw | cover(W, H, CropPosition::TopLeft) |
| Glide | fit=crop-top-left |
| Imagine | ❌ (caller computes Point manually; only Center enum) |
| JoliCode | crop_position: start | end (1-axis only — no NW/NE/SW/SE) |
| Liip | ❌ (compass on background/watermark only, not crop) |
| Spatie | crop(W, H, CropPosition::TopLeft) |
| TYPO3 MP | 🟡 (only imgproxy/optimole builders; not wired) |
Manual pixel rectangle
Specify the crop region in absolute pixel coordinates: a starting point (x, y) and a size (w, h). Useful when the coordinates come from upstream — an image editor, a database, a CMS field.
| CDN | API |
|---|---|
| Cloudflare | ❌ (trim is edge-trim, not arbitrary rect) |
| Cloudinary | c_crop,w_W,h_H,x_X,y_Y |
| Imagor | AxB:CxD (start point + end point) |
| imgix | rect=X,Y,W,H |
| imgproxy | c:W:H:nowe:X:Y |
| Intervention | crop(W, H, X, Y) |
| Thumbor | AxB:CxD |
| wsrv.nl | cx=X&cy=Y&cw=W&ch=H |
| PHP library | API |
|---|---|
| Chainsaw | manualCrop(W, H, X, Y) |
| Glide | crop=W,H,X,Y |
| Imagine | crop(new Point(X, Y), new Box(W, H)) |
| JoliCode | crop: { start_x: X, start_y: Y, width: W, height: H } |
| Liip | crop: { start: [X, Y], size: [W, H] } |
| Spatie | manualCrop(W, H, X, Y) |
| TYPO3 MP | setCrop(W, H, X, Y) |
Focal-point crop
Like a compass crop, but the anchor is an arbitrary point given as normalised coordinates: (0.0, 0.0) is top-left, (1.0, 1.0) is bottom-right. The crop window is positioned so the focal point stays inside it (and ideally near its centre).
| CDN | API |
|---|---|
| Cloudflare | gravity=fxXfy (decimal × ratio) |
| Cloudinary | ❌ (g_xy_center centres the crop on the point — different operation) |
| Imagor | focal(fx,fy) filter |
| imgix | crop=focalpoint&fp-x=fx&fp-y=fy |
| imgproxy | g:fp:fx:fy |
| Intervention | ❌ (compute manual rect) |
| Thumbor | ❌ (focal() filter accepts a rect, not a point) |
| wsrv.nl | a=focal&fpx=fx&fpy=fy |
| PHP library | API |
|---|---|
| Chainsaw | cover(W, H, Anchor::focal(x, y)) |
| Glide | fit=crop-X-Y (percent ints, e.g. crop-25-75) |
| Imagine | ❌ |
| JoliCode | crop: { start_x: '50%', start_y: '50%', ... } (percent strings) |
| Liip | ❌ |
| Spatie | focalCropAndResize(W, H, fxPct, fyPct) |
| TYPO3 MP | ❌ |
Focal-point crop with zoom
Same as focal-point crop, plus a magnification factor around the point. Useful for portrait thumbnails that should “zoom in” on a face rather than show the whole shoulders-up region.
| CDN | API |
|---|---|
| Cloudflare | 🟡 (gravity=face + zoom only) |
| Cloudinary | ❌ |
| Imagor | ❌ |
| imgix | fp-z=N |
| imgproxy | ❌ |
| Intervention | ❌ |
| Thumbor | ❌ |
| wsrv.nl | ❌ |
| PHP library | API |
|---|---|
| Chainsaw | cover(W, H, Anchor::focal(x, y, zoom)) |
| Glide | fit=crop-X-Y-Z (percent + zoom int, e.g. crop-25-75-2) |
| Imagine | ❌ |
| JoliCode | ❌ |
| Liip | ❌ |
| Spatie | ❌ |
| TYPO3 MP | ❌ |
Smart / saliency crop
The image service analyses the source and picks the most “interesting” rectangle of the requested size — typically by visual saliency, contrast, or edge detection. Often called auto or smart by image services. The result is content-aware: a portrait gets cropped around the face, a landscape around the dominant feature.
| CDN | API |
|---|---|
| Cloudflare | gravity=auto |
| Cloudinary | g_auto |
| Imagor | smart segment |
| imgix | crop=edges (or crop=entropy) |
| imgproxy | g:sm |
| Intervention | ❌ |
| Thumbor | smart segment |
| wsrv.nl | a=attention (or a=entropy) |
| PHP library | API |
|---|---|
| Chainsaw | cover(W, H, Anchor::smart()) |
| Glide | ❌ |
| Imagine | ❌ |
| JoliCode | ❌ |
| Liip | ❌ |
| Spatie | ❌ |
| TYPO3 MP | ❌ (constants exist but not wired) |
Entropy crop
A specific kind of smart crop: pick the rectangle with the highest Shannon entropy (busiest area). Tends to favour textured regions over flat ones.
| CDN | API |
|---|---|
| Cloudflare | 🟡 (under gravity=auto) |
| Cloudinary | 🟡 (under g_auto:classic) |
| Imagor | 🟡 (under smart) |
| imgix | crop=entropy |
| imgproxy | 🟡 (under g:sm) |
| Intervention | ❌ |
| Thumbor | 🟡 (under smart) |
| wsrv.nl | a=entropy |
| PHP library | API |
|---|---|
| Chainsaw | cover(W, H, Anchor::entropy()) |
| Glide | ❌ |
| Imagine | ❌ |
| JoliCode | ❌ |
| Liip | ❌ |
| Spatie | ❌ |
| TYPO3 MP | ❌ |
Attention crop
Another smart variant, based on a visual-attention model rather than entropy. Often gives a different result than entropy on the same image — both are “smart”, but they answer “interesting where?” differently.
| CDN | API |
|---|---|
| Cloudflare | 🟡 (under gravity=auto) |
| Cloudinary | 🟡 (under g_auto:subject) |
| Imagor | 🟡 (under smart) |
| imgix | ❌ |
| imgproxy | 🟡 (under g:sm) |
| Intervention | ❌ |
| Thumbor | 🟡 (under smart) |
| wsrv.nl | a=attention |
| PHP library | API |
|---|---|
| Chainsaw | cover(W, H, Anchor::attention()) |
| Glide | ❌ |
| Imagine | ❌ |
| JoliCode | ❌ |
| Liip | ❌ |
| Spatie | ❌ |
| TYPO3 MP | ❌ |
Face-detection crop
A smart crop biased toward detected faces. If multiple faces are detected, the crop is positioned to include them all (or the largest, depending on the service).
| CDN | API |
|---|---|
| Cloudflare | gravity=face |
| Cloudinary | g_face (or g_faces) |
| Imagor | 🟡 (under smart) |
| imgix | crop=faces (or fit=facearea) |
| imgproxy | obj:face (Pro) |
| Intervention | ❌ |
| Thumbor | 🟡 (under smart) |
| wsrv.nl | ❌ |
| PHP library | API |
|---|---|
| Chainsaw | cover(W, H, Anchor::face()) |
| Glide | ❌ |
| Imagine | ❌ |
| JoliCode | ❌ |
| Liip | ❌ |
| Spatie | ❌ |
| TYPO3 MP | ❌ |
Object-class detection crop
A smart crop biased toward a named class — dog, car, food. The service runs object detection and centres the crop on the matching region. Limited to services with an object detector and a published class vocabulary.
| CDN | API |
|---|---|
| Cloudflare | ❌ |
| Cloudinary | g_auto:<object> (e.g. g_auto:dog) |
| Imagor | ❌ |
| imgix | ❌ |
| imgproxy | obj:<class> / objw: (Pro) |
| Intervention | ❌ |
| Thumbor | ❌ |
| wsrv.nl | ❌ |
| PHP library | API |
|---|---|
| Chainsaw | cover(W, H, Anchor::object('dog')) |
| Glide | ❌ |
| Imagine | ❌ |
| JoliCode | ❌ |
| Liip | ❌ |
| Spatie | ❌ |
| TYPO3 MP | ❌ |
Family 5 — Aspect-ratio targeting
Specify the output’s aspect ratio without specifying absolute dimensions. The dimensions follow from the source size and the chosen ratio.
Crop to aspect ratio
Specify a target aspect (e.g. 16 : 9). The largest rectangle of that ratio that fits inside the source is cut, anchored at the centre (or another anchor).
| CDN | API |
|---|---|
| Cloudflare | ❌ |
| Cloudinary | ar_16:9 |
| Imagor | ❌ |
| imgix | ar=16:9 |
| imgproxy | ❌ (no ratio-only primitive — exar requires w/h) |
| Intervention | ❌ |
| Thumbor | ❌ |
| wsrv.nl | ❌ |
| PHP library | API |
|---|---|
| Chainsaw | cropToRatio('16:9') |
| Glide | ❌ |
| Imagine | ❌ |
| JoliCode | ❌ |
| Liip | ❌ |
| Spatie | ❌ |
| TYPO3 MP | ❌ |
Pad to aspect ratio
The mirror operation: extend the canvas so its aspect ratio matches the target, padding the new space with a background colour. The source is preserved at its original size; only the surrounding canvas grows.
| CDN | API |
|---|---|
| Cloudflare | ❌ |
| Cloudinary | ar_16:9,c_pad |
| Imagor | ❌ |
| imgix | ar=16:9&fit=fill&fill=solid |
| imgproxy | ❌ (no ratio-only primitive — exar requires w/h) |
| Intervention | ❌ |
| Thumbor | ❌ |
| wsrv.nl | ❌ |
| PHP library | API |
|---|---|
| Chainsaw | padToRatio('16:9', '#fff') |
| Glide | ❌ |
| Imagine | ❌ |
| JoliCode | ❌ |
| Liip | ❌ |
| Spatie | ❌ |
| TYPO3 MP | ❌ |
Family 6 — Content-detected
The output dimensions aren’t specified by the caller — they’re decided by the image’s own content.
Auto-trim uniform borders
Detect and remove pixels around the edges that match a reference colour (typically the corner colour, or a user-supplied colour, with a tolerance). The output dimensions are derived from where the trim algorithm decides the content begins.
| CDN | API |
|---|---|
| Cloudflare | trim=border&trim.tolerance=N |
| Cloudinary | e_trim:N:col |
| Imagor | trim:[anchor][:tol] |
| imgix | trim=color&trim-tol=N&trim-color=fff |
| imgproxy | t:thr:col |
| Intervention | trim($tol) |
| Thumbor | trim:[anchor][:tol] |
| wsrv.nl | trim=N&tbg=fff |
| PHP library | API |
|---|---|
| Chainsaw | trim(N) |
| Glide | ❌ |
| Imagine | ❌ |
| JoliCode | ❌ |
| Liip | ❌ |
| Spatie | ❌ |
| TYPO3 MP | ❌ |
Modifiers and ordering
Two cross-cutting concerns apply on top of the catalogue above:
- Pre-crop then resize — apply an explicit pixel rectangle (Family 4) before the main resize. Useful when the source has known padding or banner areas that should never appear in any output.
- Resize then post-crop — chain the operations the other way. Less common, but sometimes intentional, especially when the resize is a scale-by-factor and the crop selects a region of the resized result.
These aren’t separate operations — they’re sequencing choices when chaining multiple operations.
For the Chainsaw API that implements many of these operations, see Resize & Fit. For the per-provider availability matrix, see Provider Support.