Reputation: 149
I can't display remote svg images in <Image>
control.
Example:
When I try to display this image, I don't see anything.
<Image Source="https://www.meteosuisse.admin.ch/static/product/resources/weather-symbols/120.svg" />
It's the same with this image
<Image Source="https://en.wikipedia.org/wiki/Scalable_Vector_Graphics#/media/File:SVG_Logo.svg" />
But if I only change the url of the image with this one which is of type JPG, everything works
<Image Source="https://aka.ms/campus.jpg" />
Am I doing something wrong?
.NET MAUI Version: 6.0.548 Microsoft Visual Studio Enterprise 2022 (64 bits) - Current Version 17.4.3
Best Regards
Tested on
I have see this question but here, the problem is only with SVG remote image.
Upvotes: 1
Views: 695
Reputation: 1
I made this. It doesnt load from a URL but it does load SVG data as a string ("<svg ..... "): https://gist.github.com/andressbarajas/c2248d5925087f5b769aacb9af8f74a8
using System.Reflection;
using System.Xml.Linq;
using SkiaSharp.Views.Maui;
using SkiaSharp.Views.Maui.Controls;
using SKSvg = SkiaSharp.Extended.Svg.SKSvg;
namespace Project.Views;
public class SvgImage : SKCanvasView
{
private Dictionary<string, string> _color_mappings = new Dictionary<string, string>();
public static BindableProperty SourceProperty = BindableProperty.Create(nameof(Source), typeof(string), typeof(SvgImage), default(string), propertyChanged: OnPropertyChanged);
public string Source
{
get => (string)GetValue(SourceProperty);
set => SetValue(SourceProperty, value);
}
public static BindableProperty ColorMappingProperty = BindableProperty.Create(nameof(ColorMapping), typeof(string), typeof(SvgImage), default(string), defaultBindingMode: BindingMode.Default, propertyChanged: OnPropertyChanged);
public string ColorMapping
{
get => (string)GetValue(ColorMappingProperty);
set => SetValue(ColorMappingProperty, value);
}
public SvgImage()
{
BackgroundColor = Colors.Transparent;
}
protected override void OnPaintSurface(SKPaintSurfaceEventArgs args)
{
base.OnPaintSurface(args);
try
{
if (!String.IsNullOrEmpty(Content))
{
using (var stream = new MemoryStream(Encoding.UTF8.GetBytes(Content)))
{
if (stream == null)
throw new Exception("SVG Stream is NULL for Content");
CreateSVG(stream, args);
}
}
}
catch (Exception ex)
{
throw new Exception("An error occured when reading the Svg Resource: " + ex.Message);
}
}
private void CreateSVG(Stream stream, SKPaintSurfaceEventArgs args)
{
try
{
var canvas = args.Surface.Canvas;
canvas.Clear();
var svg = new SKSvg();
// Clear all mappings
_color_mappings.Clear();
// Populate mappings
if(!String.IsNullOrEmpty(ColorMapping))
{
var mappings = ColorMapping.Split(';');
foreach (var map in mappings)
{
var key_and_value = map.Split('=');
_color_mappings.Add(key_and_value[0], key_and_value[1]);
}
}
if (_color_mappings.Count > 0)
{
using (var sr = new StreamReader(stream))
{
var svg_xml = XDocument.Load(sr);
var fill_color_elements = svg_xml.Root.Descendants().Where(x => x.Attribute("fill") != null).ToList();
foreach (var element in fill_color_elements)
{
var key = element.Attribute("fill").Value;
if (_color_mappings.ContainsKey(key))
element.Attribute("fill").Value = _color_mappings[key];
}
var style_elements = svg_xml.Root.Descendants().Where(x => x.Attribute("style") != null).ToList();
foreach (var element in style_elements)
{
var style_key = element.Attribute("style").Value;
var keys = style_key.Split(';');
for (var i = 0; i < keys.Count(); i++)
{
if (keys[i].Contains("fill"))
{
var key_split = keys[i].Split("fill:");
if (_color_mappings.ContainsKey(key_split[1]))
{
keys[i] = "fill:" + _color_mappings[key_split[1]];
}
}
}
element.Attribute("style").Value = String.Join(';', keys);
}
using (var mem_stream = new MemoryStream())
{
svg_xml.Save(mem_stream);
mem_stream.Position = 0;
svg.Load(mem_stream);
}
}
}
else
{
stream.Position = 0;
svg.Load(stream);
}
var info = args.Info;
canvas.Translate(info.Width / 2f, info.Height / 2f);
var bounds = svg.ViewBox;
float xRatio = info.Width / bounds.Width;
float yRatio = info.Height / bounds.Height;
var ratio = Math.Min(xRatio, yRatio);
canvas.Scale(ratio);
canvas.Translate(-bounds.MidX, -bounds.MidY);
canvas.DrawPicture(svg.Picture);
}
catch (Exception ex)
{
throw new Exception("An error occured when reading the Svg Resource: " + ex.Message);
}
}
public void Refresh()
{
InvalidateSurface();
}
private static void OnPropertyChanged(BindableObject bindable, object oldValue, object newValue)
{
var skCanvasView = bindable as SKCanvasView;
skCanvasView?.InvalidateSurface();
}
protected override void OnBindingContextChanged()
{
base.OnBindingContextChanged();
InvalidateSurface();
}
protected override void OnSizeAllocated(double width, double height)
{
base.OnSizeAllocated(width, height);
InvalidateSurface();
}
}
Upvotes: 0