问题
I am using a Signature pad for Xamarin forms and I am trying to set the signature to an image source.
I am trying to convert stream to ByteArray but the converted bytearray is always empty.
In the function ReadFully I have tried two approaches but both returned 0 bytes
Could you please suggest where i am going wrong.
I looked up on the internet found these links
https://forums.xamarin.com/discussion/19853/load-image-form-byte-array
XAML
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="Radical.Views.DocketSignaturePad"
xmlns:acr="clr-namespace:Acr.XamForms.SignaturePad;assembly=Acr.XamForms.SignaturePad"
Title="DocketSignaturePad">
<ScrollView>
<StackLayout Padding="10">
<acr:SignaturePadView
x:Name="padView"
HeightRequest="320"
WidthRequest="240"
BackgroundColor="White"
CaptionText="Caption This"
CaptionTextColor="Black"
ClearText="Clear Me!"
ClearTextColor="Red"
PromptText="Prompt Here"
PromptTextColor="Red"
SignatureLineColor="Aqua"
StrokeColor="Black"
StrokeWidth="2"
/>
<Button Clicked="OnChangeTheme" Text="Change Theme" />
<Button Clicked="SaveSignature" Text="Save signature"/>
<Image x:Name="signatureImage" WidthRequest="300" HeightRequest="100" BackgroundColor="Blue"/>
</StackLayout>
</ScrollView>
</ContentPage>
Xaml.cs
async void SaveSignature(object sender, EventArgs e)
{
List<DrawPoint> signaturePoints = padView.GetDrawPoints().ToList();
if (signaturePoints.Count > 0)
{
Stream imageAsBytes = new MemoryStream(ReadFully(padView.GetImage(ImageFormatType.Jpg)));
signatureImage.Source = ImageSource.FromStream(() => new MemoryStream(ReadFully(padView.GetImage(ImageFormatType.Jpg))));
}
}
public static byte[] ReadFully(Stream input)
{
using (MemoryStream ms = new MemoryStream())
{
input.CopyTo(ms);
return ms.ToArray();
}
//byte[] buffer = new byte[16 * 1024];
//using (MemoryStream ms = new MemoryStream())
//{
// int read;
// while ((read = input.Read(buffer, 0, buffer.Length)) > 0)
// {
// ms.Write(buffer, 0, read);
// }
// return ms.ToArray();
//}
}
回答1:
You can use this code, it worked for me:
Stream image = await sign.GetImageStreamAsync(SignatureImageFormat.Png);
img_signature.Source = ImageSource.FromStream(() => image);
回答2:
I probably could fix your code using conversions but for my taste there are too many conversions you don't need. The problem is that after you get a stream it points to the end of it. Here is more optimal way of doing what you need:
void SaveSignature(object sender, EventArgs e)
{
List<DrawPoint> signaturePoints = padView.GetDrawPoints().ToList();
if (signaturePoints.Count > 0)
{
Stream s = padView.GetImage(ImageFormatType.Png);
//s.Position = 0; or
s.Seek(0,SeekOrigin.Begin);
signatureImage.Source = ImageSource.FromStream(() => { return s; });
}
}
Note, it doesn't work using JPG well because you cannot make it transparent background so it shows just black rectangle. It works with PNG. You might take a look on scaling an image if pad is not the same size as your image
One more thing: I would try to avoid putting stacklayout into scrollview. On small devices instead of writing the signature it tries to move the screen.
And I would look at more modern control from Xamarin
来源:https://stackoverflow.com/questions/44648485/stream-to-bytearray-convert-signature-pad-to-image