EDIT
With the DrawingView, I have migrated an old application from Xamarin Forms that actually made use of the SignaturePad control. HOWEVER, the problem with the new DrawingView is that the lines and points generated are far fewer than what was generated in comparison to the old SignaturePad.
My question is how do we generate a full version of the signature on the server, given the lines/points generated by the DrawingView, because when we use the current server implementation and Lines/Points (which is far less in comparison to the SignaturePad), the signature is not complete, in fact it is VERY pixelated.
I have implemented the DrawingView as a replacement for the older SignaturePad that was part of Xamarin.Forms.
The issue is that the old Xamarin.Forms SignaturePad would generate a larger number of Points/Lines to make up the image if it was rendered on a web page after the Points/Lines were uploaded to a server, BUT the DrawingView does not generate the same amount of points.
Is anyone able to tell me if I am missing something or how to correctly get all the points, because I do need the full signature displayed on the web after server upload.
Here is my implementation:
XAML
<toolkit:DrawingView
x:Name="MySignatureView"
BackgroundColor="DarkGray"
DrawingLineCompletedCommand="{Binding ExecuteGetSignatureCommand}"
HorizontalOptions="FillAndExpand"
IsEnabled="{Binding IsLocked}"
IsMultiLineModeEnabled="True"
LineColor="Black"
LineWidth="1"
Lines="{Binding DrawingLines, Mode=TwoWay}"
ShouldClearOnFinish="False"
VerticalOptions="FillAndExpand"/>
CODE BEHIND
MySignatureView.DrawAction = (ICanvas canvas, RectF rect) =>
{
canvas.DrawString("Signature", 0, 0, (int)MySignatureView.Width, (int)MySignatureView.Height, HorizontalAlignment.Center, VerticalAlignment.Center);
};
VIEW MODEL
[ObservableProperty]
ObservableCollection<IDrawingLine> drawingLines = new();
public async void ExecuteGetSignature(IDrawingLine drawingLines)
{
try
{
List<Point>? currentPoints = drawingLines.Points.Select(pointF => new Point(pointF.X, pointF.Y)).ToList();
UpdatePoints(currentPoints);
var gestureImage = new Image();
using var stream = await drawingLines.GetImageStream(gestureImage.Width, gestureImage.Height, Colors.Gray.AsPaint());
using var memoryStream = new MemoryStream();
await stream.CopyToAsync(memoryStream);
stream.Position = 0;
memoryStream.Position = 0;
SignatureAsBase64String = Convert.ToBase64String(memoryStream.ToArray());
}
catch (Exception ex)
{
ex.Tag();
}
}
public double ZeroTolerance { get; set; }
private void UpdatePoints(List<Point> points)
{
//List<Point>? myPoints = points.Select(point => new Point { X = point.X, Y = point.Y }).ToList();
List<Point[]> lines = new();
List<Point> currentLine = new();
ZeroTolerance = 0;
foreach (Point point in points)
{
if ((Math.Abs(point.X) < ZeroTolerance && (Math.Abs(point.Y) < ZeroTolerance)) || (Math.Abs(point.X - (-10000)) < ZeroTolerance && Math.Abs(point.Y - (-10000)) < ZeroTolerance))
{
lines.Add(currentLine.ToArray());
currentLine = new List<Point>();
}
else
{
currentLine.Add(point);
}
}
lines.Add(currentLine.ToArray());
Lines = lines;
}
