Can the color of an existing svg be changed from code? #166
-
Sorry for being lazy and not properly reading the documentation. For our project it would be really helpful if we could alter the color of an existing svg. So, for instance the fill style of a path like this: If not how could such functionality be added? Where in the code should I look and would you be interested in a MR? |
Beta Was this translation helpful? Give feedback.
Replies: 4 comments 2 replies
-
I think you can do some manipulation but only after loading SvgDocument but but when it's rendering |
Beta Was this translation helpful? Give feedback.
-
Thanks! We are not using the SvgDocument in our code so I need to did deeper into this library. I just cloned it on Windows but get by a lot of build errors if I open the sln in Visual Studio. Is there anything specific I need to do? Call some build command? The build.cmd and build.ps1 scripts fails complaining that Svg.Generators.csproj was not found. Should I generate some source somehow? |
Beta Was this translation helpful? Give feedback.
-
I ended up using the class below. In our code we used The purpose of this code is to override the existing fill and stroke. Please tell me if there are more efficient ways of doing this, or more reuse of existing methods. For instance iterating over all SvgElements in a SvgDocument, or a simpler way to convert the SvgDocument to a SKPicture. using Svg.Model;
using Svg.Skia;
using Svg;
using SkiaSharp;
using System.Drawing;
namespace MN.MapsuiBuilder.LayerBuilders
{
public class SvgLoader
{
public static SKPicture? ToSKPicture(Stream stream, Color? fillColor = null, Color? strokeColor = null)
{
var svgDocument = SvgExtensions.Open(stream);
if (svgDocument is null) return null;
var elements = GetAllElements(svgDocument.Children);
foreach (var element in elements)
{
if (element.Fill is not null && fillColor is { })
element.Fill = new SvgColourServer(fillColor.Value);
if (element.Stroke is not null && strokeColor is { })
element.Stroke = new SvgColourServer(strokeColor.Value);
}
return ToSKPicture(svgDocument);
}
private static SKPicture? ToSKPicture(SvgDocument svgDocument)
{
var skiaModel = new SkiaModel(new SKSvgSettings());
var assetLoader = new SkiaAssetLoader(skiaModel);
var model = SvgExtensions.ToModel(svgDocument, assetLoader, out var _, out _);
return skiaModel.ToSKPicture(model);
}
public static List<SvgElement> GetAllElements(SvgElementCollection elements)
{
var result = new List<SvgElement>();
foreach (var element in elements)
{
result.Add(element);
if (element.Children.Count > 0)
result.AddRange(GetAllElements(element.Children));
}
return result;
}
}
} |
Beta Was this translation helpful? Give feedback.
-
Hi pauldendulk, thanks for the solution to this. I was looking for the same thing. I'm using this Avalonia.Svg.Skia lib to read files into my app, either of two ways:
I'm wondering how I would turn either the Avalonia.Svg.Skia.Svg or Avalonia.Controls.Image into a Stream, to then call the SKToPicture(Stream stream, Color? fillColor = null, Color? strokeColor = null) method you wrote? Thanks in advance for any info! Also thanks much to wieslawsoltes! Nice library! James |
Beta Was this translation helpful? Give feedback.
I think you can do some manipulation but only after loading SvgDocument but but when it's rendering