How SVG feMorphology Erode and Dilate Filters Work

The SVG <feMorphology> filter primitive transforms graphical elements by either expanding or shrinking their visual boundaries. By altering the pixel structure of a source graphic based on mathematical morphology, this filter provides two fundamental operations: erode (thinning or shrinking) and dilate (thickening or expanding). This article explains how the underlying pixel operations work, how the operator and radius attributes control the transformation, and how these effects can be practically implemented in SVG graphics.

The Underlying Mechanism of feMorphology

The <feMorphology> filter operates on a pixel-by-pixel grid using a concept known as a structuring element or kernel. As the filter evaluates each pixel in the source graphic, it scans the surrounding neighborhood defined by the specified radius. Depending on the chosen operator, it evaluates the color and alpha channel values of those neighboring pixels and replaces the target pixel with either the minimum or maximum value found.

The Dilate Operation (operator="dilate")

The dilate operation expands the visual footprint of an SVG shape or text.

The Erode Operation (operator="erode")

The erode operation contracts or thins the visual footprint of an SVG element.

Controlling the Effect with the radius Attribute

The magnitude of the dilation or erosion is governed by the radius attribute:

Syntax and Implementation

Below is a standard implementation showing both operations applied within an SVG filter definition:

<svg width="400" height="200" xmlns="http://www.w3.org/2000/svg">
  <defs>
    <!-- Dilate Filter: Thickens the element -->
    <filter id="thicken">
      <feMorphology operator="dilate" radius="2" in="SourceGraphic" result="thickened" />
    </filter>

    <!-- Erode Filter: Thins the element -->
    <filter id="thin">
      <feMorphology operator="erode" radius="1.5" in="SourceGraphic" result="thinned" />
    </filter>
  </defs>

  <text x="20" y="50" font-size="30">Standard Text</text>
  <text x="20" y="100" font-size="30" filter="url(#thicken)">Dilated Text</text>
  <text x="20" y="150" font-size="30" filter="url(#thin)">Eroded Text</text>
</svg>

By leveraging feMorphology individually or in a pipeline with primitives like <feComposite> and <feGaussianBlur>, you can manipulate geometric boundaries dynamically without altering the original vector paths.