Replace SVG Colors in C# – Bulk Recolor SVG Files

Quick Answer

To replace SVG colors in C#, load the file with SVGDocument, find color-bearing attributes such as fill, stroke, and stop-color, compare their values with the source color, update matching values with SetAttribute(), and save the SVG. For imported files, also inspect inline style attributes because they can override presentation attributes.

This article shows how to replace colors throughout an SVG file using Aspose.SVG for .NET. It focuses on practical bulk recoloring tasks: changing brand colors, recoloring icons, replacing gradient stop colors, and preparing SVG files for consistent rendering or conversion.

If you need to inspect an SVG palette before changing it, see Extract SVG Colors in C#. It shows how to list colors from attributes, inline styles, and gradient stops.

You will learn how to:

Where SVG Colors Can Be Stored

SVG colors are not always stored in one place. A simple file may use presentation attributes such as fill="#ff0000", while SVG files exported from design tools often use inline styles or CSS rules.

LocationExampleReplace directly?Notes
Presentation attributefill="#d32f2f"YesCommon for generated SVG and simple icons
Stroke attributestroke="rgb(211, 47, 47)"YesUsed for outlines, lines, paths, and icon strokes
Gradient stopstop-color="#d32f2f"YesUsed inside <linearGradient> and <radialGradient>
Inline stylestyle="fill:#d32f2f; stroke:black"Yes, but parse carefullyInline styles override presentation attributes
Paint server referencefill="url(#gradient1)"NoReplace colors inside the referenced gradient instead
Special keywordfill="none" or currentColorUsually noPreserve semantic paint values unless your workflow requires otherwise

For a detailed explanation of SVG style priority, see SVG CSS vs Inline Styles vs Presentation Attributes.

Replace Fill, Stroke, and Gradient Attribute Colors

The examples in this article use replace-svg-colors.svg, a small SVG file that contains color values in three common places: presentation attributes, gradient stops, and inline style attributes.

 1<svg height="300" width="600" xmlns="http://www.w3.org/2000/svg">
 2    <path d="M 85 135 Q 25 -20 180 100 T 170 250 T 220 150 T 290 50" stroke="grey" stroke-width="3" fill="none" />
 3    <defs>
 4        <radialGradient id="myRG" cx="0.5" cy="0.5" r="0.8" fx="0.5" fy="0.5" spreadMethod="pad">
 5            <stop offset="0%" stop-color="bisque" />
 6            <stop offset="40%" stop-color="grey" />
 7            <stop offset="60%" stop-color="silver" />
 8        </radialGradient>
 9    </defs>
10    <path d="M 120,120 A 70,40 0 0 0 150,180 A 70,50 0 1 1 120,120" style="stroke: grey; stroke-width:3" fill="url(#myRG)" />
11    <circle cx="260" cy="60" r="40" style="stroke: grey; stroke-width:3" fill="url(#myRG)" />
12</svg>

The following example replaces a specific color wherever it appears in common SVG color attributes. The source color can be a color name, HEX value, RGB value, or another CSS color value, but this example compares the literal attribute text. The example handles fill, stroke, and stop-color, so it works for shapes, paths, text outlines, and gradient stops.

In this example, only colors equal to grey are replaced. Other colors, such as bisque or silver, remain unchanged. Color declarations inside the style attribute are handled separately in the next example.

  1. Load the SVG file using the SVGDocument class.
  2. Select all SVG elements with QuerySelectorAll("*").
  3. Check color-bearing attributes with GetAttribute().
  4. Compare the attribute value with the source color name.
  5. Replace matching values using SetAttribute().
  6. Save the updated SVG.
 1using Aspose.Svg;
 2using Aspose.Svg.Dom;
 3using System;
 4using System.IO;
 5
 6// Load the source SVG file that contains color attributes and gradient stops.
 7using var document = new SVGDocument(Path.Combine(DataDir, "replace-svg-colors.svg"));
 8
 9// Define the SVG color to find and the replacement color to apply.
10string sourceColor = "grey";
11string newColor = "#1976d2";
12
13// Limit replacement to SVG attributes that commonly store visible colors.
14string[] colorAttributes = { "fill", "stroke", "stop-color" };
15
16// Find all SVG elements and inspect their color-related attributes.
17foreach (Element element in document.QuerySelectorAll("*"))
18{
19    foreach (string attributeName in colorAttributes)
20    {
21        string value = element.GetAttribute(attributeName);
22
23        if (!string.IsNullOrWhiteSpace(value) &&
24            value.Trim().Equals(sourceColor, StringComparison.OrdinalIgnoreCase))
25        {
26            // Replace only attributes whose value matches the source color.
27            element.SetAttribute(attributeName, newColor);
28        }
29    }
30}
31
32// Save the SVG file with replaced attribute colors.
33document.Save(Path.Combine(OutputDir, "replace-svg-colors-attributes.svg"));

This approach is intentionally strict: it replaces only attribute values equal to grey, ignoring case. For example, it replaces stroke="grey" and stop-color="grey", but it does not replace stop-color="bisque", stop-color="silver", or style="stroke: grey" (see color replacement result (b)).

If you need to treat equivalent color formats as the same color, for example grey, #808080, and rgb(128, 128, 128), normalize values with the Color class before comparison.

Replace Colors in Inline Style Attributes

Many SVG files contain styles like this:

1<path style="stroke: grey; stroke-width:3" fill="url(#myRG)" />

If you only set fill or stroke presentation attributes, the inline style value may still win in the SVG cascade. For bulk recoloring, inspect and update the style attribute as well.

 1using Aspose.Svg;
 2using Aspose.Svg.Dom;
 3using System;
 4using System.Collections.Generic;
 5using System.IO;
 6
 7// Load the source SVG file that contains inline style declarations.
 8using var document = new SVGDocument(Path.Combine(DataDir, "replace-svg-colors.svg"));
 9
10// Define the inline CSS color value to find and the new color value.
11string sourceColor = "grey";
12string newColor = "#1976d2";
13
14// Select only SVG elements that have a style attribute.
15foreach (Element element in document.QuerySelectorAll("[style]"))
16{
17    string style = element.GetAttribute("style");
18    var updatedDeclarations = new List<string>();
19
20    // Split the inline style into individual CSS declarations.
21    foreach (string declaration in style.Split(';', StringSplitOptions.RemoveEmptyEntries))
22    {
23        string[] parts = declaration.Split(':', 2);
24
25        if (parts.Length != 2)
26        {
27            // Keep malformed or nonstandard declarations unchanged.
28            updatedDeclarations.Add(declaration.Trim());
29            continue;
30        }
31
32        string property = parts[0].Trim();
33        string value = parts[1].Trim();
34
35        // Replace only the CSS declaration value that matches the source color.
36        if (value.Equals(sourceColor, StringComparison.OrdinalIgnoreCase))
37        {
38            value = newColor;
39        }
40
41        updatedDeclarations.Add($"{property}: {value}");
42    }
43
44    // Write the updated inline style back to the SVG element.
45    element.SetAttribute("style", string.Join("; ", updatedDeclarations));
46}
47
48// Save the SVG file with replaced inline style colors.
49document.Save(Path.Combine(OutputDir, "replace-svg-colors-inline-style.svg"));

This example preserves unrelated style declarations such as stroke-width, opacity, font-family, or transform. See color replacement result (c).

If your SVG file contains complex CSS rules inside a <style> element, update the CSS rules intentionally instead of doing broad string replacement. For general style normalization workflows, see Modify SVG Styles Programmatically in C#.

Replace a Color Palette

Branding workflows often require replacing several colors at once. In that case, use a dictionary with the source colors and replacement colors.

 1using Aspose.Svg;
 2using Aspose.Svg.Dom;
 3using System;
 4using System.Collections.Generic;
 5using System.IO;
 6
 7// Load the source SVG file whose colors will be replaced as a palette.
 8using var document = new SVGDocument(Path.Combine(DataDir, "replace-svg-colors.svg"));
 9
10// Map each source SVG color to its replacement color.
11var palette = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase)
12{
13    ["grey"] = "#a02601",
14    ["bisque"] = "#ffd1cf",
15    ["silver"] = "#fa90a7"
16};
17
18// Search only SVG attributes that store visible paint colors.
19string[] colorAttributes = { "fill", "stroke", "stop-color" };
20
21// Replace several known SVG colors with a new palette.
22foreach (Element element in document.QuerySelectorAll("*"))
23{
24    foreach (string attributeName in colorAttributes)
25    {
26        string value = element.GetAttribute(attributeName);
27
28        if (!string.IsNullOrWhiteSpace(value) &&
29            palette.TryGetValue(value.Trim(), out string replacement))
30        {
31            // Apply the matching palette color to the current SVG attribute.
32            element.SetAttribute(attributeName, replacement);
33        }
34    }
35}
36
37// Save the SVG file with the new color palette.
38document.Save(Path.Combine(OutputDir, "replace-svg-colors-palette.svg"));

Use this pattern for SVG templates, generated reports, white-label graphics, icon sets, and theme switching.

Color Replacement Results

The figure shows the source SVG file (a), the result of replacing attribute colors (b), the result of replacing inline style colors (c), and the result of replacing a color palette (d).

Source SVG and three SVG color replacement results in C#

Common Mistakes and Fixes

ProblemCauseFix
Colors other than the source color are replacedThe code replaces every replaceable color instead of checking the current value against sourceColorKeep the color match check when you want one-color replacement
The color does not changeInline style overrides the fill or stroke attributeUpdate the style attribute or remove the conflicting declaration
Some shapes remain unchangedThey use stroke, stop-color, or CSS rules instead of fillCheck all color-bearing locations before saving
Gradient colors remain unchangedThe element uses fill="url(#id)"Update the <stop> elements inside the referenced gradient
The icon becomes filled unexpectedlyThe code replaced fill="none"Preserve none unless you intentionally want to fill open shapes
Theme-based SVG stops workingThe code replaced currentColorKeep currentColor when the SVG should inherit color from CSS
A color comparison failsThe same color is written in different formats, such as grey, #808080, and rgb(128, 128, 128)Normalize values with Color.FromString() before comparing, or use one consistent color format in your SVG

FAQ

Can I replace all SVG colors with one color?
Yes. Iterate through fill, stroke, stop-color, and inline style declarations, skip none, currentColor, and url(#id), then set every replaceable color to the target value.

Should I use string replacement on the SVG file?
Use DOM-based replacement when possible. It is safer because it targets attributes and elements instead of changing unrelated text, IDs, URLs, or metadata.

How do I replace colors in gradients?
Find <stop> elements and update their stop-color attributes. If a shape uses fill="url(#gradient)", the visible colors are defined in the gradient stops, not on the shape itself.

Why does SetAttribute("fill", "...") not affect my SVG?
The element may have an inline style attribute, a CSS rule, fill="none", or a gradient reference. Inspect the SVG source and follow the style priority rules before applying a replacement.

Related Resources