v7.1.2-34 Latest Stable Release

The FX Special Effects Image Operator

Explore ImageMagick’s FX special effects operator, a powerful pixel-level expression language for image manipulation. Learn how to apply mathematical formulas to transform, distort, composite, and analyze images with flexible scripting examples and advanced functions.

quickstart.sh
# Install via your favorite Package Manager
$ brew install imagemagick
# Convert PNG to WebP with compression
$ magick input.png -quality 85 output.webp
# Resize image maintaining aspect ratio
$ magick input.jpg -resize 800x600^ output.jpg

The FX special effects image operator applies mathematical expressions to each pixel channel of an image. The FX expression language provides a flexible mechanism for fine-grained pixel-level transformations, analysis, and custom procedural generation.

Procedural Generation

Create procedural canvases, mathematical gradients, colormaps, and fractal sets from equations.

Geometric Distortion

Translate, flip, mirror, rotate, scale, shear, and warp images using custom coordinate functions.

Compositing & Channel Routing

Move color channels between images, convolve pixel neighborhoods, and merge multiple inputs seamlessly.

Examples & Scripting Workflows

1. Simple Channel Modification (Canvas Color Swap)

Convert a black canvas to navy blue by assigning a fixed fractional value to the blue channel:

$ magick -size 64x64 canvas:black -channel blue -fx "1/2" fx_navy.png
Black canvas input
Input
Navy canvas output
Output
2. Non-linear Sigmoidal Contrast Transfer Function

Apply an exponential contrast curve formula to adjust image luminance response:

$ magick rose: -fx "(1.0/(1.0+exp(10.0*(0.5-u)))-0.006693)*1.0092503" rose-sigmoidal.png
Rose original
Original
Rose high contrast
High Contrast
3. Custom Variables & Radial Gradients

Assign intermediate variable calculations (Xi, Yj) to construct mathematical gradients:

$ magick -size 70x70 canvas: -fx "Xi=i-w/2; Yj=j-h/2; 1.2*(0.5-hypot(Xi,Yj)/70.0)+0.5" radial-gradient.png
Radial gradient
Generated Pattern

Inject custom statistical Gaussian noise into an image pipeline:

$ magick photo.jpg -fx 'iso=32; rone=rand(); rtwo=rand(); \
  myn=sqrt(-2*ln(rone))*cos(2*Pi*rtwo); myntwo=sqrt(-2*ln(rtwo))* \
  cos(2*Pi*rone); pnoise=sqrt(p)*myn*sqrt(iso)* \
  channel(4.28,3.86,6.68)/255; max(0,p+pnoise)' noisy.png

Leverage iterative for() loops to map complex polynomial fractal calculations into color lookup tables (CLUT):

$ magick -size 400x400 xc:gray -fx " \
  Xi=2.4*i/w-1.2; \
  Yj=2.4*j/h-1.2; \
  for (pixel=0.0, (hypot(Xi,Yj) < 2.0) && (pixel < 1.0), \
    delta=Xi^2-Yj^2; \
    Yj=2.0*Xi*Yj+0.2; \
    Xi=delta+0.4; \
    pixel+=0.00390625 \
  ); \
  pixel == 1.0 ? 0.0 : pixel" \
  \( -size 1x1 xc:white xc:red xc:orange xc:yellow xc:green1 xc:cyan xc:blue \
     xc:blueviolet xc:white -reverse +append -filter Cubic -resize 1024x1! \) \
  -clut -rotate -90 julia-set.png
Julia Fractals

Use the debug() statement inside FX loops to calculate math output directly to standard output:

$ magick xc:gray -fx " \
  for (prime=2, prime < 30, composite=0; \
    for (nn=2, nn < (prime/2+1), if ((prime % nn) == 0, composite++, ); nn++); \
      if (composite <= 0, debug(prime), ); prime++)" null:

For more script examples, visit the official ImageMagick Usage Guide.

The Anatomy of an FX Expression

Symbol Description
u, vFirst (u) and second (v) images in the active sequence list.
s, t, nCurrent image reference (s), image sequence index (t), total image count (n).
i, j, pCurrent column offset (i), row offset (j), target pixel channel accessor (p).
w, h, zCurrent image width (w), height (h), channel depth (z).
r, g, bRed, green, and blue values of the target pixel.
c, m, y, kCyan, magenta, yellow, and black values for CMYK target pixels.
a, oAlpha and opacity values of the target pixel.
intensity, lumaCalculated pixel color intensity or luma weighted scalar.
hue, saturation, lightnessPixel color channels extracted from HSL space representation.
page.x, page.y, page.widthCanvas page offsets and dimensions.
mean, standard_deviation, kurtosisImage or individual channel statistics (e.g. mean.r, s.kurtosis).
Constant Value / Description
E, eEuler's constant (e ≈ 2.7182818)
Epsilon, epsilonSmallest difference between distinct values (1.0 × 10⁻¹²)
QuantumRange, quantumrangeMaximum channel scalar value dependent on build depth (e.g. 65535)
QuantumScale, quantumscaleReciprocal of QuantumRange (1.0 / QuantumRange)
PHI, phiGolden Ratio (φ ≈ 1.6180339)
PI, Pi, piArchimedes' constant (π ≈ 3.1415926)

Supported native built-in mathematical functions:

abs() acos() acosh() airy() alt() asin() asinh() atan() atan2() ceil() clamp() cos() cosh() debug() drc() epoch() erf() exp() floor() gauss() gcd() hypot() int() isnan() j0() j1() jinc() ln() log() logtwo() magicktime() max() min() mod() not() pow() rand() round() sign() sin() sinc() sinh() sqrt() squish() tan() tanh() trunc()
Color Constructors: rgb(), rgba(), hsl(), hsla(), cmyk()
Channel Constructor: channel(); This takes up to 5 expressions, and returns whichever is appropriate for the channel being processed, in order of RGBKA or CMYKA, e.g., channel(r, g+b, g-b).
Iterators & Control Flow: for(init, condition, step), while(cond, stmt), do(cond, stmt), if(cond, then, else)
Operator Precedence
  • Precedence 1 (Power): ^
  • Precedence 2 (Unary/Multiplicative): -, *, /, %
  • Precedence 3 (Additive/Shift): +, -, <<, >>
  • Precedence 4 (Relational): <, <=, >, >=, ==, !=
  • Precedence 5 (Bitwise/Logical): &, |, ~, &&, ||, !
  • Precedence 6 (Conditional): ?: (Ternary operator)
  • Precedence 7 (Assignment): =, +=, -=, *=, /=, %=
Control Structures & Conditionals
Ternary Operator (condition ? expr1 : expr2)
Evaluates and returns expr1 if condition is non-zero (true); otherwise returns expr2.
Example: u > 0.5 ? 1.0 : 0.0
if(condition, then_statement, else_statement)
Conditional execution function. Evaluates then_statement if condition holds true, or the optional else_statement if false.
Example: if(u.r > 0.5, 1, 0)
while(condition, statement)
Repeatedly executes statement as long as condition evaluates to non-zero (true).
Example: while(x < 10, x+=1)
do(condition, statement)
Executes statement at least once, then repeatedly executes it as long as condition evaluates to non-zero (true).
Example: do(x < 10, x+=1)
Syntax & Semantics Rules
  • Symbols and built-in identifiers are case insensitive.
  • Ternary conditionals (x ? y : z) can be nested within another ternary.
  • Single-character variable names are strictly reserved for built-ins. Use multi-character names for custom variables (e.g. Xi, iso).
  • Unary operators take a lower priority than binary operators. For instance, -3^2 evaluates as -(3^2) = -9. Always use parentheses ((-3)^2 = 9) to explicitly indicate order.
  • Implicit multiplication is not permitted; e.g., 1/2x returns a syntax exception, instead use 1/(2*x) explicitly.

Source Images & Pixel Addressing

Image Sequence Indexes

Use index qualifiers on image references to query other images in the current sequence stack. Zero is the first image; negative indexes count backward from the end.

  • u[0] First image
  • u[2] Third image
  • u[-1] Last image in list
  • u[t] Current image (s)
$ magick img1.jpg img2.jpg img3.jpg -fx "(u+u[2])/2" out.jpg
Pixel & Neighborhood Access

All color values are normalized in the range 0.0 to 1.0. Use relative indexing (brackets) or absolute coordinates (braces) with p:

Relative Offset:
p[-1,-1].r
Red channel of the pixel diagonally top-left from current location
Absolute Offset:
p{12,34}.b
Blue channel value at column 12, row 34
Format Escapes & String Evaluations

Instead of modifying pixels directly on an image canvas, FX formulas can be embedded into string escapes for metadata queries or dynamic settings:

%[fx:] Value Escape

Evaluated once per image in sequence. Returns numerical computation result directly into format attributes.

$ magick rose: -format '%[fx:w*h]' info:
%[pixel:] Color Escape

Evaluates formula across color channels and automatically outputs a standardized CSS color or hex string.

$ magick rose: -format '%[pixel:p{0,0}]' info: