0

I work on a Xamarin.Forms app where I've implemented a signature control with the Syncfusion SfSignaturePad

I would like to send the signature image to an API.

For this, I've converted the ImageSource of the related signature to a byte array like this:

SfSignaturePad signaturePad;

public byte[] SignaturePadImage { get; set; }

private void BtnConvert_Tapped(object sender, EventArgs e)
{
    signaturePad.Save();
    if (signaturePad.ImageSource != null)
    {
        StreamImageSource streamImageSource = (StreamImageSource)signaturePad.ImageSource;
        System.Threading.CancellationToken cancellationToken =
            System.Threading.CancellationToken.None;
        Task<Stream> task = streamImageSource.Stream(cancellationToken);
        Stream stream = task.Result;

        // store bytes
        SignaturePadImage = new byte[stream.Length];
        stream.Read(SignaturePadImage, 0, SignaturePadImage.Length);
    }
}

This allows me to set the byte array as Source of an Image to display the corresponding image.

But when I send the byte array to the API, the image format is not recognized, as it based on a Xamarin.Forms.ImageSource.

So I would like to "convert" my ImageSource to a formated image (as .PNG, .BMP, ...) before to recover the byte array.

What should be the better approach to achieve this?

3
  • I'd suggest using the Xamarin SignaturePad control instead. The SF control is not very flexible Commented Apr 15, 2021 at 17:34
  • This one? Is it still "functional" after 3 years? Commented Apr 15, 2021 at 17:46
  • yes, I just used it in a project and it worked great Commented Apr 15, 2021 at 18:21

2 Answers 2

1

According to jason's opinion, I use Xamarin.Controls.SignaturePad, and I get image by signatureView.GetImageStreamAsync(SignatureImageFormat.Png) and convert to byte[].

Firstly, install Xamarin.Controls.SignaturePad.Forms

Then using SignaturePadView, please following code.

<ContentPage
x:Class="FormsSample.images.Page1"
xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:controls="clr-namespace:SignaturePad.Forms;assembly=SignaturePad.Forms">
<ContentPage.Content>
    <StackLayout x:Name="imagestack">
       
        <Button
            x:Name="btn2"
            Clicked="btn2_Clicked"
            Text="get image from signturePadview" />
        <controls:SignaturePadView
            x:Name="signatureView"
            BackgroundColor="Gray"
            StrokeColor="White"
            StrokeWidth="3" />
    </StackLayout>
</ContentPage.Content>
private async void btn2_Clicked(object sender, EventArgs e)
    {
        var image = new Xamarin.Forms.Image();
        byte[] buffer;
        using (Stream bitmap = await signatureView.GetImageStreamAsync(SignatureImageFormat.Png))
        {
            if(bitmap!=null)
            {
                long length = bitmap.Length;
                buffer = new byte[length];
                bitmap.Read(buffer, 0, (int)length);

                var stream1 = new MemoryStream(buffer);
                image.Source = ImageSource.FromStream(() => stream1);

                image.WidthRequest = 50;
                image.HeightRequest = 50;
                imagestack.Children.Add(image);
            }
           
        }
    }

I convert signatureView image source to byte[], then display on the Xamarin.Forms Image, the byte[] buffer is the Image Byte array, that you want to get.

Sign up to request clarification or add additional context in comments.

Comments

0

Thanks for your suggestions.

Finally, I've implemented another solution, as FFImageLoading is already used on this project.

For this, I use CachedImage instead of Image:

<ffimageloading:CachedImage x:Name="signatureImg"
        Source="{Binding Source={x:Reference SignatureView}, Path=SignaturePadImageSource, Mode=TwoWay}"
        IsVisible="{Binding Source={x:Reference SignatureView}, Path=IsSignatureMode, Converter={StaticResource InverseBoolConverter}}"
        VerticalOptions="FillAndExpand"
        BackgroundColor="{Binding Source={x:Reference SignatureView}, Path=BackColor}" />

Then subscribe to the Success event from CachedImage in the constructor of my control:

public CustomSignature()
{
    InitializeComponent();
    signaturePad = sfSignaturePad;
    IsSignatureMode = true;
    signatureImg.Success += SignatureImg_Success;
}

Then I can use the GetImageAsPngAsync() method from FFImageLoading.

private async void SignatureImg_Success(object sender, CachedImageEvents.SuccessEventArgs e)
{
    SignaturePadImage2Bytes = await signatureImg.GetImageAsPngAsync((int)signatureImg.Width, (int)signatureImg.Height);
}

I can share the PNG bytes array like this.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.