如何在 Xamarin 表单上使用 SkiaSharp 加载文件 .svg?
How to load file .svg with SkiaSharp on Xamarin forms?
如何在 Xamarin Forms(Android 和 iOS)上使用 SkiaSharp 加载文件 .svg
。
我试过,但我无法加载。
我尝试使用SkiaSharp.Extended并参考了他们的Demo,但仍然无法加载。
我做错了什么吗?
请帮帮我!
B1> 在您的项目 Xamarin forms
中创建文件夹 Images
并在此处保存图像 .svg
。确保 select Build Action
为 "EmbeddedResource"
B2> 下载所需的库,例如:
SkiaSharp
、SkiaSharp.Views.Forms
、SkiaSharp.Extended.Svg
B3> 在 behind code
,在页面的构造函数中使用方法 LoadSvg(xCanvasView.AutomationId)
(Example
:页面是 ListNewConversationPage
) .并声明所需的功能:
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> 在 .xaml
文件中,将其与 .svg
图像一起使用 image_part_circle.svg
<forms:SKCanvasView x:Name="xCanvasView"
PaintSurface="OnPainting"
HorizontalOptions="FillAndExpand"
VerticalOptions="FillAndExpand"
BackgroundColor="Blue"
AutomationId="image_part_circle.svg" />
查看更多内容
需要安装以下软件包 SkiaSharp.Views.Forms
、SkiaSharp.Extended
和 SkiaSharp.Svg
。从那里我创建了一个自定义 Xamarin.Forms 控件,如下所示:
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);
}
}
}
我必须指定 Svg 图像的程序集和文件夹路径才能找到图像,任何 Svg 图像都应设置为 EmbeddedResource
。然后使用Xaml中的控件:
<controls:SvgImage AssemblyName="SkiaSharpSvgImage" Source="Resources.tux1.svg" />
我创建的整个开源测试项目可以在Github上查看。此外,该回购协议可能会得到改进,但那是我第一次使用 SkiaSharp Svg 图像并测试所有内容。
如何在 Xamarin Forms(Android 和 iOS)上使用 SkiaSharp 加载文件 .svg
。
我试过
我尝试使用SkiaSharp.Extended并参考了他们的Demo,但仍然无法加载。
我做错了什么吗?
请帮帮我!
B1> 在您的项目 Xamarin forms
中创建文件夹 Images
并在此处保存图像 .svg
。确保 select Build Action
为 "EmbeddedResource"
B2> 下载所需的库,例如:
SkiaSharp
、SkiaSharp.Views.Forms
、SkiaSharp.Extended.Svg
B3> 在 behind code
,在页面的构造函数中使用方法 LoadSvg(xCanvasView.AutomationId)
(Example
:页面是 ListNewConversationPage
) .并声明所需的功能:
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> 在 .xaml
文件中,将其与 .svg
图像一起使用 image_part_circle.svg
<forms:SKCanvasView x:Name="xCanvasView"
PaintSurface="OnPainting"
HorizontalOptions="FillAndExpand"
VerticalOptions="FillAndExpand"
BackgroundColor="Blue"
AutomationId="image_part_circle.svg" />
查看更多内容
需要安装以下软件包 SkiaSharp.Views.Forms
、SkiaSharp.Extended
和 SkiaSharp.Svg
。从那里我创建了一个自定义 Xamarin.Forms 控件,如下所示:
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);
}
}
}
我必须指定 Svg 图像的程序集和文件夹路径才能找到图像,任何 Svg 图像都应设置为 EmbeddedResource
。然后使用Xaml中的控件:
<controls:SvgImage AssemblyName="SkiaSharpSvgImage" Source="Resources.tux1.svg" />
我创建的整个开源测试项目可以在Github上查看。此外,该回购协议可能会得到改进,但那是我第一次使用 SkiaSharp Svg 图像并测试所有内容。