I'm working on a .NET 8 MAUI project and I have encountered the following issue. The app has different types of users, and based on the user, it changes its primary color at runtime. This is to make the app visually distinct for each type of user.
The problem arises with SVG images used in the app, which have sections that display the primary color. For example, an image of a person might have their shirt in the primary color. This section should change color based on the user, as I mentioned earlier.
In MAUI, for the Android platform, I understand that images are processed in PNG format. I've managed to keep the images in SVG format by storing them in the Resources -> Raw folder and setting their Build Action to MauiAsset.
The approach I'm trying to use for changing the color is via SkiaSharp, which seemed to be the simplest option I found. However, it is not working as expected.
The code I can provide is:
private async void LoadAndModifySvg()
{
// Path to the original SVG file
string originalSvgFileName = "man_and_car.svg";
// Read SVG content
string svgContent = await ReadSvgFileAsync(originalSvgFileName);
// Replace the color #F27B13 with #0000FF
svgContent = Regex.Replace(svgContent, @"#F27B13", "#0000FF", RegexOptions.IgnoreCase);
// Load the SVG content into SKSvg
_svg = new SkiaSharp.Extended.Svg.SKSvg();
using (var stream = new MemoryStream(System.Text.Encoding.UTF8.GetBytes(svgContent)))
{
_svg.Load(stream);
}
// Update the view
CanvasView.InvalidateSurface();
}
private void CanvasView_PaintSurface(object sender, SKPaintSurfaceEventArgs e)
{
if (_svg == null)
return;
var canvas = e.Surface.Canvas;
canvas.Clear(SKColors.White);
// Adjust the size and position of the SVG on the canvas
var scale = Math.Min(e.Info.Width / _svg.Picture.CullRect.Width,
e.Info.Height / _svg.Picture.CullRect.Height);
canvas.Scale((float)scale);
// Draw the SVG
canvas.DrawPicture(_svg.Picture);
}
// Method to read the SVG file as text
private async Task<string> ReadSvgFileAsync(string fileName)
{
using (var stream = await FileSystem.OpenAppPackageFileAsync(fileName))
using (var reader = new StreamReader(stream))
{
return await reader.ReadToEndAsync();
}
}
From the XAML side, I have:
<skia:SKCanvasView x:Name="CanvasView" PaintSurface="CanvasView_PaintSurface"
HeightRequest="450"
AbsoluteLayout.LayoutBounds="1.1,1"
AbsoluteLayout.LayoutFlags="PositionProportional"
ZIndex="0"/>
I would appreciate it if someone could help me. The goal is to modify the color of a specific section of an SVG image in MAUI .NET 8. Thank you.
After further analysis of my code I managed to find the error. It was on the xaml side, since it used an absolutlayout. It did not allow the SKCanvasView to render correctly.
It was solved by using the SKCanvasView, outside of an absolutlayout. A grid was designed to allow correct rendering.
<skia:SKCanvasView x:Name="CanvasView" PaintSurface="CanvasView_PaintSurface"
HeightRequest="450"
ZIndex="0"/>
The aforementioned code together with the code used from c# works perfectly.