Filters & Effects
blur(int $radius)
Baseline
Supported on all 10 providers.
CFCNIMIMIMIXIPIVTHWS
- All providers
- Radius scaling differs per provider; same input produces visibly different blur strengths across backends.
Gaussian blur. Range: 0–100.
$image->blur(20);
sharpen(int $amount)
Baseline
Supported on all 10 providers.
CFCNIMIMIMIXIPIVTHWS
- Cloudflare
- Quantized to 11 steps (0..10) — visible banding at small mid-range deltas.
- Imagekit
- Documented as 0..100; ImageKit's imgix migration guide hints at a ×20 scaling. Empirical calibration deferred; expect output to differ from the documented range until verified.
- Imgproxy
- Pro tier: ~10 sigma steps.
- Thumbor
- Quantized to 11 amount steps.
- Cloudinary / Imagor / Imgix / Wserv
- Full 0..100 precision preserved.
Sharpen. Range: 0–100.
$image->sharpen(50);
brightness(int $amount)
Widely available
Unsupported on Imagekit.
CFCNIMIMIMIXIPIVTHWS
- Cloudflare
- Multiplier scale (1.0 = no change).
- Cloudinary / Imagor / Imgix / Imgproxy / Intervention / Thumbor / Wserv
- Standard -100..100 scale.
Adjust brightness. Range: -100 to 100.
$image->brightness(30); // brighter
$image->brightness(-30); // darker
contrast(int $amount)
Widely available
Unsupported on Imagekit and Imagine.
CFCNIMIMIMIXIPIVTHWS
- Cloudflare
- Multiplier scale (1.0 = no change).
- Cloudinary / Imagor / Imgix / Imgproxy / Intervention / Thumbor / Wserv
- Standard -100..100 scale.
Adjust contrast. Range: -100 to 100.
$image->contrast(30);
gamma(float $gamma)
Widely available
Unsupported on Imagekit, Imagor and Thumbor.
CFCNIMIMIMIXIPIVTHWS
- Cloudinary
- Translates `pct = round((gamma - 1) × 100)`, clamped to -50..150. Large multipliers saturate.
- Imgix
- Same translation as Cloudinary, clamped to -100..100.
Gamma correction. Range: 0.1–9.99.
$image->gamma(2.0);
pixelate(int $size)
Limited availability
Only supported on Cloudinary, Imagor, Imgix, Imgproxy and Intervention.
CFCNIMIMIMIXIPIVTHWS
Pixelate with block size. Range: 0–1000.
$image->pixelate(10);
greyscale()
Baseline
Supported on all 10 providers.
CFCNIMIMIMIXIPIVTHWS
Convert to greyscale.
$image->greyscale();
Emitted as saturation=0.01 (not 0) to preserve alpha on transparent sources; Cloudflare’s saturation=0 codepath forces JPEG output and fills transparency with black. See CloudflareProvider notes. saturation(-100) receives the same rewrite.
sepia()
Limited availability
Only supported on Cloudinary, Imgix, Imgproxy, Intervention and Wserv.
CFCNIMIMIMIXIPIVTHWS
- All providers
- Filter curve varies; no cross-provider reference implementation.
Apply sepia tone.
$image->sepia();
saturation(int $amount)
Widely available
Unsupported on Imagekit.
CFCNIMIMIMIXIPIVTHWS
- Cloudflare
- Multiplier scale (1.0 = no change). `saturation=0` codepath emits `saturation=0.01` to preserve alpha (forces JPEG otherwise).
- Cloudinary / Imagor / Imgix / Imgproxy / Intervention / Thumbor / Wserv
- Standard -100..100 scale.
Adjust color saturation. Range: -100 to 100 (-100 = greyscale, 0 = unchanged, 100 = max).
$image->saturation(50); // more vibrant
$image->saturation(-100); // greyscale equivalent
saturation(-100) is emitted as saturation=0.01 (not 0) to preserve alpha on transparent sources. See greyscale() above.
hue(int $angle)
Widely available
Unsupported on Cloudflare, Imagekit, Imgproxy and Thumbor.
CFCNIMIMIMIXIPIVTHWS
Rotate the hue around the color wheel. Range: 0 to 360 degrees.
$image->hue(180); // invert complementary colors
negate()
Limited availability
Only supported on Cloudinary, Imagine, Imgix, Intervention and Wserv.
CFCNIMIMIMIXIPIVTHWS
Invert all colors (photographic negative).
$image->negate();
flip(FlipDirection $direction)
Baseline
Supported on all 10 providers.
CFCNIMIMIMIXIPIVTHWS
Mirror the image.
use Timber\Chainsaw\Enum\FlipDirection;
$image->flip(FlipDirection::Horizontal);
$image->flip(FlipDirection::Vertical);
rotate(int $degrees, ?string $background = null)
Baseline
Supported on all 10 providers.
CFCNIMIMIMIXIPIVTHWS
- All providers
- Quarter-turns are byte-rotations and consistent across all providers.
- Cloudflare / Cloudinary / Imagekit / Imagor / Imgix / Imgproxy / Intervention / Thumbor / Wserv
- Arbitrary angles use different resampling algorithms and background-fill defaults; output dimensions and edge handling vary subtly.
- Imagekit
- No dedicated rotation-background param; Rotate's `$background` is emitted as the page-level `bg-`, sharing the key with the Background manipulator (last-write wins when both are stacked).
Rotate the image clockwise by $degrees. Quarter-turns (90 / 180 / 270) are portable across all providers; arbitrary angles are only supported by Cloudinary, ImageKit, wsrv.nl, and the local providers (Intervention, Imagine) — others throw UnsupportedManipulator. Negative angles rotate counter-clockwise. The clockwise convention matches CSS transform: rotate() and most CDN URL APIs; Imagor, Thumbor, and Intervention natively rotate counter-clockwise but Chainsaw normalises this so visual output matches across every backend.
$background is the fill colour for revealed corners on non-quarter rotations (e.g. '#ffffff'). Quarter-turns ignore it.
$image->rotate(90);
$image->rotate(180);
$image->rotate(45); // arbitrary, non-portable
$image->rotate(45, background: '#3b82f6'); // with bg fill
autoOrient()
Baseline
Supported on all 10 providers.
CFCNIMIMIMIXIPIVTHWS
Apply the EXIF orientation tag to the pixel data and strip the tag. Most CDN providers (Cloudflare, Cloudinary, Imagor, imgix, wsrv) auto-orient by default, so this is effectively a no-op there. Imgproxy and Intervention require it to be explicit.
$image->autoOrient();
background(string $color)
Baseline
Supported on all 10 providers.
CFCNIMIMIMIXIPIVTHWS
Set a background color (visible when the source has transparency).
$image->background('#ff6600');
border(int $width, ...)
Widely available
Unsupported on Cloudflare, Imagor, Thumbor and Wserv.
CFCNIMIMIMIXIPIVTHWS
Add a border around the image.
use Timber\Chainsaw\Enum\BorderType;
use Timber\Chainsaw\Enum\Unit;
// Overlay (no size change)
$image->border(10, color: '#ff0000');
// Expand canvas
$image->border(20, color: '#1a1a1a', type: BorderType::Expand);
// Shrink image to fit border
$image->border(10, type: BorderType::Shrink);
// Percentage-based
$image->border(5, unit: Unit::Percent);