Effects filter the image, adjust its colors, or lay a color over it, with or without resizing.

Every effect is off unless the group 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. 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:

URL

/contrast=2/-/brightness=30/src/photos/beach.jpg

Elixir

ImagePipe.URL.new()
|> ImagePipe.URL.group(contrast: 2)
|> ImagePipe.URL.group(brightness: 30)

Where effects sit among the other stages is described under processing order.

Filters

blur

Accepts a number 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 doesn't change it.

URL

/w=800/blur=2/src/photos/beach.jpg

Elixir

ImagePipe.URL.group(builder, resize: [width: 800], blur: 2)

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.
  • start and stop are 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.

URL

/progressive-blur=4,down,0.2,0.8/src/photos/beach.jpg

Elixir

ImagePipe.URL.group(builder, progressive_blur: [sigma: 4, direction: :down, start: 0.2, stop: 0.8])

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.

URL

/w=400/sharpen=1.5/src/photos/beach.jpg

Elixir

ImagePipe.URL.group(builder, resize: [width: 400], sharpen: 1.5)

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.

URL

/pixelate=8/src/photos/beach.jpg

Elixir

ImagePipe.URL.group(builder, pixelate: 8)

Color adjustments

gray

A boolean. Default: false.

Converts the image to grayscale. Transparency is kept.

URL

/gray/src/photos/beach.jpg

Elixir

ImagePipe.URL.group(builder, gray: true)

bitonal

A boolean. 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.

URL

/bitonal/src/scans/receipt.png

Elixir

ImagePipe.URL.group(builder, bitonal: true)

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.

URL

/monochrome=0.8,704214/src/photos/beach.jpg

Elixir

ImagePipe.URL.group(builder, monochrome: [intensity: 0.8, color: "704214"])

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.

URL

/duotone=1,123456,efab89/src/photos/beach.jpg

Elixir

ImagePipe.URL.group(builder, duotone: [intensity: 1, shadow: "123456", highlight: "efab89"])

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.

URL

/brightness=-20/src/photos/beach.jpg

Elixir

ImagePipe.URL.group(builder, brightness: -20)

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.

URL

/contrast=1.25/src/photos/beach.jpg

Elixir

ImagePipe.URL.group(builder, contrast: 1.25)

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 for full grayscale, since saturation=0 fails with 400.

URL

/saturation=0.7/src/photos/beach.jpg

Elixir

ImagePipe.URL.group(builder, saturation: 0.7)

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.

URL

/colorize=0.3,red,keep-alpha/src/logos/brand.png

Elixir

ImagePipe.URL.group(builder, colorize: [opacity: 0.3, color: "red", keep_alpha: true])

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.

URL

/gradient=0.8,black,down,0.2,0.9/src/photos/beach.jpg

Elixir

ImagePipe.URL.group(builder,
  gradient: [opacity: 0.8, color: "black", direction: :down, start: 0.2, stop: 0.9]
)