How Grain Extract Blending Works in GIMP
GIMP’s Grain Extract layer mode isolates fine textures, noise, and high-frequency details from an image by comparing two layers. It achieves this effect through a specific arithmetic operation: it subtracts the pixel values of the source (upper) layer from the destination (lower) layer, and then adds an offset of 128 to shift the baseline to neutral 50% gray. This article explains the exact mathematical sequence GIMP uses during this process and how each step affects the resulting output.
The Mathematical Formula
In digital image processing, GIMP evaluates blending modes per channel (Red, Green, Blue). When using standard 8-bit precision (where values range from 0 to 255), the Grain Extract calculation is represented by the formula:
\[\text{Output} = (\text{Destination} - \text{Source}) + 128\]
In linear or floating-point workflows (where values range from 0.0 to 1.0), the formula scales accordingly:
\[\text{Output} = (\text{Destination} - \text{Source}) + 0.5\]
- Destination (Bottom Layer): The underlying image containing the base data.
- Source (Top Layer): The active layer set to "Grain Extract."
- 128 (or 0.5): The neutral gray midpoint value added to anchor the differences.
Step 1: Subtracting Source from Destination
The first half of the operation computes the raw difference between the layers:
\[\Delta = \text{Destination} - \text{Source}\]
Because pixel data cannot normally be negative, GIMP internally performs this calculation using signed data types or floating-point math before final rendering. The intermediate results yield three distinct possibilities:
- Destination equals Source (\(\text{Destination} = \text{Source}\)): The difference is \(0\). Both layers have identical color and luminosity at that coordinate.
- Destination is brighter than Source (\(\text{Destination} > \text{Source}\)): The subtraction yields a positive integer (up to \(+255\)).
- Destination is darker than Source (\(\text{Destination} < \text{Source}\)): The subtraction yields a negative integer (down to \(-255\)).
At this intermediate stage, negative values cannot be displayed in standard 8-bit space without clipping to pure black (\(0\)). To prevent the loss of detail where the source is brighter than the destination, GIMP introduces the offset.
Step 2: Adding the 128 Neutral Gray Offset
To map both positive and negative differences into a visible spectrum, GIMP adds an offset of 128:
\[\text{Output} = \Delta + 128\]
This shifts the entire calculation so that zero difference aligns with mid-tone gray:
- No Difference: \(0 + 128 = 128\) (Medium Gray). Areas where both layers are identical turn flat gray.
- Positive Differences (Highlights): If the destination is brighter, the result is shifted above 128 (e.g., \(+40 + 128 = 168\)). These become light areas relative to the neutral gray background.
- Negative Differences (Shadows): If the destination is darker, the result is pulled below 128 (e.g., \(-40 + 128 = 88\)). These become dark areas relative to the neutral gray background.
Clipping and Clamping
In standard 8-bit integer modes, the final value is clamped between \(0\) and \(255\):
- Any result exceeding \(255\) is clipped to \(255\) (pure white).
- Any result falling below \(0\) is clipped to \(0\) (pure black).
When working with high bit-depth precision (16-bit, 32-bit floating point) via GEGL, values outside the standard bounds are preserved rather than clipped, maintaining dynamic range for subsequent operations.
Reversing the Operation: Grain Merge
The Grain Extract formula is mathematically linked to GIMP's Grain Merge mode. Grain Merge reverses the extraction by performing the inverse operation:
\[\text{Result} = (\text{Destination} + \text{Source}) - 128\]
Because Grain Extract stores relative variations around a 128 midpoint, combining an extracted texture layer back onto an image using Grain Merge perfectly cancels out the 128 offset, reconstructing the original pixel values without data loss.