Current section
Files
Jump to
Current section
Files
docs/processing/effects.md
# Effects
Effects filter the image, adjust its colors, or lay a color over it, with or
without resizing.
Every effect is off unless the [group](../requesting-images.md#processing-groups)
sets it, and each group starts with all effects off again. Effects that take a
color accept a hex value or a CSS name, as described under
[colors](../requesting-images.md#colors). On a grayscale image, `monochrome`,
`duotone`, `colorize`, and `gradient` produce a color image only if one of
their colors isn't a neutral gray. The default `monochrome` and `duotone`
colors keep it gray.
## Effect order
Effects run after resizing and cropping, in this order, whatever order the URL
lists them in:
`blur`, `progressive-blur`, `sharpen`, `pixelate`, `gray`, `bitonal`,
`monochrome`, `duotone`, `brightness`, `contrast`, `saturation`, `colorize`,
`gradient`
To run them in another order, put them in separate groups. This URL adjusts
brightness after contrast:
<!-- tabs-open -->
### URL
```text
/contrast=2/-/brightness=30/src/photos/beach.jpg
```
### Elixir
```elixir
ImagePipe.URL.new()
|> ImagePipe.URL.group(contrast: 2)
|> ImagePipe.URL.group(brightness: 30)
```
<!-- tabs-close -->
Where effects sit among the other stages is described under
[processing order](../processing.md#processing-order).
## Filters
### blur
Accepts a [number](../requesting-images.md#numbers) from `0` to `1000`, the
Gaussian blur sigma. Default: none. `blur=0` has no effect.
Blurs the whole image. Larger values blur more. The sigma is in output pixels,
so [`dpr`](resize.md#dpr) doesn't change it.
<!-- tabs-open -->
### URL
```text
/w=800/blur=2/src/photos/beach.jpg
```
### Elixir
```elixir
ImagePipe.URL.group(builder, resize: [width: 800], blur: 2)
```
<!-- tabs-close -->
### progressive-blur
Accepts `sigma,direction,start,stop`. Only the sigma is required:
- `sigma` is the maximum blur, a number from `0` to `1000`. `0` has no effect.
- `direction` is `down` (default), `left`, `up`, or `right`, or an angle in
degrees, as described under [gradient](#gradient).
- `start` and `stop` are [fractions](../requesting-images.md#fractions) of the
distance across the image, in that direction. They default to `0` and `1`.
Default: none. The image is sharp before `start`, and the blur grows to the full
sigma at `stop`. Swapping `start` and `stop` reverses the ramp, and equal values
switch from sharp to fully blurred in one step. The sigma is in output pixels,
so `dpr` doesn't change it. A progressive blur is slower than `blur`.
The values are positional, so you can't skip one: to set `start`, also write a
direction, as in `progressive-blur=4,down,0.5`. An empty value, such as
`progressive-blur=4,,0.5`, fails with `400`.
<!-- tabs-open -->
### URL
```text
/progressive-blur=4,down,0.2,0.8/src/photos/beach.jpg
```
### Elixir
```elixir
ImagePipe.URL.group(builder, progressive_blur: [sigma: 4, direction: :down, start: 0.2, stop: 0.8])
```
<!-- tabs-close -->
### sharpen
Accepts a number from `0.000001` to `10`, the sharpening sigma, or `0` to
disable the effect. Default: none.
Sharpens edges. The sigma is in output pixels, so `dpr` doesn't change it.
<!-- tabs-open -->
### URL
```text
/w=400/sharpen=1.5/src/photos/beach.jpg
```
### Elixir
```elixir
ImagePipe.URL.group(builder, resize: [width: 400], sharpen: 1.5)
```
<!-- tabs-close -->
### pixelate
Accepts a whole number from `1` to `2147483647`, the block size in pixels. Default: none.
`pixelate=1` has no effect.
Replaces the image with square blocks of one color each. The block size is in
output pixels, so `dpr` doesn't change it. `pixelate=0` fails with `400`.
<!-- tabs-open -->
### URL
```text
/pixelate=8/src/photos/beach.jpg
```
### Elixir
```elixir
ImagePipe.URL.group(builder, pixelate: 8)
```
<!-- tabs-close -->
## Color adjustments
### gray
A [boolean](../requesting-images.md#booleans). Default: `false`.
Converts the image to grayscale. Transparency is kept.
<!-- tabs-open -->
### URL
```text
/gray/src/photos/beach.jpg
```
### Elixir
```elixir
ImagePipe.URL.group(builder, gray: true)
```
<!-- tabs-close -->
### bitonal
A [boolean](../requesting-images.md#booleans). Default: `false`.
Converts the image to pure black and white: pixels darker than middle gray (128
on a 0 to 255 scale) become black, and the rest become white. Transparency is
kept, including partial transparency.
<!-- tabs-open -->
### URL
```text
/bitonal/src/scans/receipt.png
```
### Elixir
```elixir
ImagePipe.URL.group(builder, bitonal: true)
```
<!-- tabs-close -->
### monochrome
Accepts `intensity,color`:
- `intensity` is a fraction. `0` has no effect, and `1` applies the full
effect.
- `color` is optional and defaults to `b3b3b3`, a light gray.
Default: none. Recolors the image in shades of one color, from black in the
shadows to `color` in the highlights.
<!-- tabs-open -->
### URL
```text
/monochrome=0.8,704214/src/photos/beach.jpg
```
### Elixir
```elixir
ImagePipe.URL.group(builder, monochrome: [intensity: 0.8, color: "704214"])
```
<!-- tabs-close -->
### duotone
Accepts `intensity`, `intensity,shadow`, or `intensity,shadow,highlight`:
- `intensity` is a fraction. `0` has no effect, and `1` applies the full
effect.
- `shadow` and `highlight` are colors. They default to black and white.
Default: none. Recolors the image with two colors: dark areas take the shadow
color and light areas the highlight color.
<!-- tabs-open -->
### URL
```text
/duotone=1,123456,efab89/src/photos/beach.jpg
```
### Elixir
```elixir
ImagePipe.URL.group(builder, duotone: [intensity: 1, shadow: "123456", highlight: "efab89"])
```
<!-- tabs-close -->
### brightness
Accepts a whole number from `-255` to `255`. Default: none. `brightness=0` has
no effect.
Adds the value to every color channel on a 0 to 255 scale. A 16-bit image
shifts by the same fraction of its range, so `brightness=40` lightens it as
much as an 8-bit image. Positive values lighten
the image and negative values darken it.
<!-- tabs-open -->
### URL
```text
/brightness=-20/src/photos/beach.jpg
```
### Elixir
```elixir
ImagePipe.URL.group(builder, brightness: -20)
```
<!-- tabs-close -->
### contrast
Accepts a number greater than 0, a contrast factor with no upper limit.
Default: none. `contrast=1` has no effect.
Multiplies every color channel's distance from 128 on a 0 to 255 scale, so
mid-gray keeps its value. With `contrast=2`, 64 becomes 0 and 192 clips to 255.
A 16-bit image scales around the same point in its range. Values above 1
increase contrast, and values below 1 reduce it. `contrast=0` fails with `400`.
<!-- tabs-open -->
### URL
```text
/contrast=1.25/src/photos/beach.jpg
```
### Elixir
```elixir
ImagePipe.URL.group(builder, contrast: 1.25)
```
<!-- tabs-close -->
### saturation
Accepts a number greater than 0, a saturation factor with no upper limit.
Default: none. `saturation=1` has no effect.
Values above 1 make colors more vivid, and values below 1 make them duller.
Use [`gray`](#gray) for full grayscale, since `saturation=0` fails with `400`.
<!-- tabs-open -->
### URL
```text
/saturation=0.7/src/photos/beach.jpg
```
### Elixir
```elixir
ImagePipe.URL.group(builder, saturation: 0.7)
```
<!-- tabs-close -->
## Color overlays
### colorize
Accepts `opacity,color` or `opacity,color,keep-alpha`:
- `opacity` is a fraction. `0` has no effect.
- `color` is required.
- `keep-alpha` is optional and keeps the image's transparency.
Default: none. Blends the color evenly over the whole image at the given
opacity. Without `keep-alpha`, the result is opaque. Transparent and partly
transparent areas are flattened onto white before the color is blended in.
<!-- tabs-open -->
### URL
```text
/colorize=0.3,red,keep-alpha/src/logos/brand.png
```
### Elixir
```elixir
ImagePipe.URL.group(builder, colorize: [opacity: 0.3, color: "red", keep_alpha: true])
```
<!-- tabs-close -->
### gradient
Accepts `opacity,color,direction,start,stop`:
- `opacity` is a fraction, the strength of the color at the end of the ramp.
`0` has no effect.
- `color` is required.
- `direction` is the way the color grows: `down` (default), `left`, `up`, or
`right`. It can also be an angle in degrees, clockwise from `down`, so `90`
is `left` and `180` is `up`. Angles may be negative or decimal and wrap
around at 360.
- `start` and `stop` are fractions of the distance across the image, in that
direction. They default to `0` and `1`.
Default: none. Lays the color over the image, transparent before `start` and
reaching full opacity at `stop`. Swapping `start` and `stop` reverses the ramp,
and equal values make a hard edge. The directions follow the image as it is
displayed after rotating, flipping, and resizing. The image's transparency is
kept.
The values are positional, so to set `start` you also write a direction. An
empty value, such as `gradient=0.8,black,,0.5`, fails with `400`.
<!-- tabs-open -->
### URL
```text
/gradient=0.8,black,down,0.2,0.9/src/photos/beach.jpg
```
### Elixir
```elixir
ImagePipe.URL.group(builder,
gradient: [opacity: 0.8, color: "black", direction: :down, start: 0.2, stop: 0.9]
)
```
<!-- tabs-close -->