How to load file .svg
with SkiaSharp on Xamarin Forms (Android and iOS).
I tried Load SVG file in Xamarin with SkiaSharp , but i can't load it.
I tried to use SkiaSharp.Extended and refer to their Demos, but still cannot load it.
Am I doing anything wrong?
please help me!
B1 > Create a folder Images
in your project Xamarin forms
and save image .svg
at this. Make sure you select Build Action
as "EmbeddedResource"
B2 > Download the required libraries like: SkiaSharp
, SkiaSharp.Views.Forms
, SkiaSharp.Extended.Svg
B3 > At behind code
, use method LoadSvg(xCanvasView.AutomationId)
at contructor of Page ( Example
: Page is ListNewConversationPage
). And declare the required functions:
private SKSvg svg;
// Get file .svg to folder Images
private static Stream GetImageStream(string svgName)
{
var type = typeof(ListNewConversationPage).GetTypeInfo();
var assembly = type.Assembly;
var abc = assembly.GetManifestResourceStream($"{assembly.GetName().Name}.Images.{svgName}");
return abc;
}
private void LoadSvg(string svgName)
{
// create a new SVG object
svg = new SKSvg();
// load the SVG document from a stream
using (var stream = GetImageStream(svgName))
svg.Load(stream);
}
private void OnPageAppearing(object sender, EventArgs e)
{
svg = null;
var page = (ContentPage)sender;
LoadSvg(page.AutomationId);
var canvas = (SKCanvasView)page.Content;
canvas.InvalidateSurface();
}
private void OnPainting(object sender, SKPaintSurfaceEventArgs e)
{
try
{
var surface = e.Surface;
var canvas = surface.Canvas;
var width = e.Info.Width;
var height = e.Info.Height;
// clear the surface
canvas.Clear(SKColors.White);
// the page is not visible yet
if (svg == null)
return;
// calculate the scaling need to fit to screen
float scaleX = width / svg.Picture.CullRect.Width;
float scaleY = height / svg.Picture.CullRect.Height;
var matrix = SKMatrix.MakeScale(scaleX, scaleY);
// draw the svg
canvas.DrawPicture(svg.Picture, ref matrix);
}
catch (Exception ex)
{
Console.WriteLine(ex);
}
}
B4 > At .xaml
file, use it with .svg
image is image_part_circle.svg
<forms:SKCanvasView x:Name="xCanvasView"
PaintSurface="OnPainting"
HorizontalOptions="FillAndExpand"
VerticalOptions="FillAndExpand"
BackgroundColor="Blue"
AutomationId="image_part_circle.svg" />
Please see more at SkiaSharp.Extended
The following packages need to be installed SkiaSharp.Views.Forms
, SkiaSharp.Extended
, and SkiaSharp.Svg
. From there I created a custom Xamarin.Forms control like so:
public class SvgImage : SKCanvasView
{
public static readonly 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 readonly BindableProperty AssemblyNameProperty = BindableProperty.Create(nameof(AssemblyName), typeof(string), typeof(SvgImage), default(string), propertyChanged: OnPropertyChanged);
public string AssemblyName
{
get => (string)GetValue(AssemblyNameProperty);
set => SetValue(AssemblyNameProperty, value);
}
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();
}
protected override void OnPaintSurface(SKPaintSurfaceEventArgs e)
{
base.OnPaintSurface(e);
try
{
var surface = e.Surface;
var canvas = surface.Canvas;
canvas.Clear();
if (string.IsNullOrEmpty(Source) || string.IsNullOrEmpty(AssemblyName))
return;
var currentAssembly = Assembly.Load(AssemblyName);
using (var stream = currentAssembly.GetManifestResourceStream(AssemblyName + "." + Source))
{
var skSvg = new SKSvg();
skSvg.Load(stream);
var skImageInfo = e.Info;
canvas.Translate(skImageInfo.Width / 2f, skImageInfo.Height / 2f);
var skRect = skSvg.ViewBox;
float xRatio = skImageInfo.Width / skRect.Width;
float yRatio = skImageInfo.Height / skRect.Height;
float ratio = Math.Min(xRatio, yRatio);
canvas.Scale(ratio);
canvas.Translate(-skRect.MidX, -skRect.MidY);
canvas.DrawPicture(skSvg.Picture);
}
}
catch (Exception exc)
{
Console.WriteLine("OnPaintSurface Exception: " + exc);
}
}
}
I did have to specify the assembly and the folder path to the Svg image for it to find the image and any Svg images should be set to EmbeddedResource
. Then to use the control in Xaml:
<controls:SvgImage AssemblyName="SkiaSharpSvgImage" Source="Resources.tux1.svg" />
The entire opensource test project I created can be viewed on Github . Also, that repo could probably be improved but that was my first runabout using SkiaSharp Svg images and testing everything out.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.