如何解决如何在SkiaSharp中任意在屏幕上从SVG字符串直接绘制SKPath?
我正在构建一个应用程序,可以发送和接收 Skia 锐利的图纸。 SKPath 被序列化为 SVG 格式并发送。然后接收端必须反序列化并从 SVG 字符串中绘制 SKPath。但是,在 OnCanvasViewPaintSurface 事件之外执行此操作似乎是不可能的。
我目前正尝试在 Xamarin 示例解决方案的手指绘画示例中执行此操作。 DrawTestLine 方法应该绘制一条我绘制并序列化为 SVG 的手绘线。实际上,它无一例外地运行,但在屏幕上什么也不画。
非常感谢您对此提供的任何帮助。
在下面查看我的修改:
using System;
using System.Collections.Generic;
using Xamarin.Forms;
using TouchTracking;
using SkiaSharp;
using SkiaSharp.Views.Forms;
namespace SkiaSharpFormsDemos.Paths
{
public partial class FingerPaintPage : ContentPage
{
Dictionary<long,SKPath> inProgressPaths = new Dictionary<long,SKPath>();
List<SKPath> completedPaths = new List<SKPath>();
SKBitmap bitmap;
SKPaint paint = new SKPaint
{
Style = SKPaintStyle.Stroke,Color = SKColors.Blue,StrokeWidth = 10,StrokeCap = SKStrokeCap.Round,StrokeJoin = SKStrokeJoin.Round
};
public FingerPaintPage()
{
InitializeComponent();
DrawTestLine();
}
private void DrawTestLine()
{
var svgPath = "M851.953 371.006L865.957 438.527L874.922 462.995L880.957 453.997L884.941 441.011L893.965 427.874L895.957 418.233L900.938 415.006L902.93 405.02L898.945 403.998";
var testPath = SKPath.ParseSvgPathData(svgPath);
bitmap = new SKBitmap(1920,1080);// (int)canvasView.CanvasSize.Width,(int)canvasView.CanvasSize.Height);
var canvas = new SKCanvas(bitmap);
canvas.Clear();
canvas.DrawPath(testPath,paint);
canvasView.InvalidateSurface();
}
void OnTouchEffectAction(object sender,TouchActionEventArgs args)
{
switch (args.Type)
{
case TouchActionType.Pressed:
if (!inProgressPaths.ContainsKey(args.Id))
{
SKPath path = new SKPath();
path.MoveTo(ConvertToPixel(args.Location));
inProgressPaths.Add(args.Id,path);
canvasView.InvalidateSurface();
}
break;
case TouchActionType.Moved:
if (inProgressPaths.ContainsKey(args.Id))
{
SKPath path = inProgressPaths[args.Id];
path.LineTo(ConvertToPixel(args.Location));
canvasView.InvalidateSurface();
}
break;
case TouchActionType.Released:
if (inProgressPaths.ContainsKey(args.Id))
{
completedPaths.Add(inProgressPaths[args.Id]);
inProgressPaths.Remove(args.Id);
canvasView.InvalidateSurface();
}
break;
case TouchActionType.Cancelled:
if (inProgressPaths.ContainsKey(args.Id))
{
inProgressPaths.Remove(args.Id);
canvasView.InvalidateSurface();
}
break;
}
}
void OnCanvasViewPaintSurface(object sender,SKPaintSurfaceEventArgs args)
{
args.Surface.Canvas.DrawBitmap(bitmap,0);
SKCanvas canvas = args.Surface.Canvas;
canvas.Clear();
foreach (SKPath path in completedPaths)
{
canvas.DrawPath(path,paint);
}
foreach (SKPath path in inProgressPaths.Values)
{
canvas.DrawPath(path,paint);
}
}
SKPoint ConvertToPixel(Point pt)
{
return new SKPoint((float)(canvasView.CanvasSize.Width * pt.X / canvasView.Width),(float)(canvasView.CanvasSize.Height * pt.Y / canvasView.Height));
}
}
}
解决方法
using System;
using System.Collections.Generic;
using Xamarin.Forms;
using TouchTracking;
using SkiaSharp;
using SkiaSharp.Views.Forms;
namespace SkiaSharpFormsDemos.Paths
{
public partial class FingerPaintPage : ContentPage
{
Dictionary<long,SKPath> inProgressPaths = new Dictionary<long,SKPath>();
List<SKPath> completedPaths = new List<SKPath>();
SKBitmap bitmap;
SKPaint paint = new SKPaint
{
Style = SKPaintStyle.Stroke,Color = SKColors.Blue,StrokeWidth = 10,StrokeCap = SKStrokeCap.Round,StrokeJoin = SKStrokeJoin.Round
};
SKPath testPath = SKPath.ParseSvgPathData("M851.953 371.006L865.957 438.527L874.922 462.995L880.957 453.997L884.941 441.011L893.965 427.874L895.957 418.233L900.938 415.006L902.93 405.02L898.945 403.998");
public FingerPaintPage()
{
InitializeComponent();
DrawTestLine();
}
private void DrawTestLine()
{
canvasView.InvalidateSurface();
}
void OnTouchEffectAction(object sender,TouchActionEventArgs args)
{
switch (args.Type)
{
case TouchActionType.Pressed:
if (!inProgressPaths.ContainsKey(args.Id))
{
SKPath path = new SKPath();
path.MoveTo(ConvertToPixel(args.Location));
inProgressPaths.Add(args.Id,path);
canvasView.InvalidateSurface();
}
break;
case TouchActionType.Moved:
if (inProgressPaths.ContainsKey(args.Id))
{
SKPath path = inProgressPaths[args.Id];
path.LineTo(ConvertToPixel(args.Location));
canvasView.InvalidateSurface();
}
break;
case TouchActionType.Released:
if (inProgressPaths.ContainsKey(args.Id))
{
completedPaths.Add(inProgressPaths[args.Id]);
inProgressPaths.Remove(args.Id);
canvasView.InvalidateSurface();
}
break;
case TouchActionType.Cancelled:
if (inProgressPaths.ContainsKey(args.Id))
{
inProgressPaths.Remove(args.Id);
canvasView.InvalidateSurface();
}
break;
}
}
void OnCanvasViewPaintSurface(object sender,SKPaintSurfaceEventArgs args)
{
bitmap = new SKBitmap((int)canvasView.CanvasSize.Width,(int)canvasView.CanvasSize.Height);
var canvas = new SKCanvas(bitmap);
canvas.Clear();
canvas.DrawPath(testPath,paint);
args.Surface.Canvas.DrawBitmap(bitmap,0);
canvas.Clear();
foreach (SKPath path in completedPaths)
{
canvas.DrawPath(path,paint);
}
foreach (SKPath path in inProgressPaths.Values)
{
canvas.DrawPath(path,paint);
}
}
SKPoint ConvertToPixel(Point pt)
{
return new SKPoint((float)(canvasView.CanvasSize.Width * pt.X / canvasView.Width),(float)(canvasView.CanvasSize.Height * pt.Y / canvasView.Height));
}
}
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。