Signature Pad unable to get the Image on to a button or in Byte stream

wajwaj USMember ✭✭

SignaturePadView mySignPad = new SignaturePadView()
{
StrokeWidth = 3,
StrokeColor = Color.Black,
BackgroundColor = Color.White,
HeightRequest = 300,
WidthRequest = 300
};
var Image = mySignPad.GetImageStreamAsync(SignatureImageFormat.Jpg);

// The above line is returning System.Threading.Tasks.Task I am unable to convert it into a Byte Stream nor able to assign the result to an image or button.

Please find what i tried below.

Scenario 1:

                    var sig = await mySignPad.GetImageStreamAsync(SignaturePad.Forms.SignatureImageFormat.Png);
        var signatureMemoryStream = sig as MemoryStream;  // here error
        byte[] data = signatureMemoryStream.ToArray();

             In the above code it is unable to convert the returned value to memory stream . I am not able to typecast it.

Scenario 2:

                     using (var signatureMemoryStream = (MemoryStream) Image)   
                            // Error (Cannot convert type System.Threading.Tasks.Task<System.IO.Stream> into      System.Io.MemoryStream)
        {
            byte[] data = signatureMemoryStream.ToArray();
        }

Any suggestions would be appreciated. Thank you.

Answers

  • RVxRVx USMember ✭✭
    edited April 2017

    I had this problem too, i ended up with this:
    the byte array it the "data"
    I read somewhere that it is a difference in the way between android and ios handles streams and garbage collection.

                if (!pad.IsBlank)
                {
    
                    try
                    {
    #if __IOS__   
                        var img = await pad.GetImageStreamAsync(SignatureImageFormat.Png);
                        var signatureMemoryStream = new MemoryStream();
                        img.CopyTo(signatureMemoryStream);
                        byte[] data = signatureMemoryStream.ToArray();
    #else
                        var img = await pad.GetImageStreamAsync(SignatureImageFormat.Png);
                        var signatureMemoryStream = (MemoryStream)img;
                        byte[] data = signatureMemoryStream.ToArray();
    #endif
    
                        string base64img = Convert.ToBase64String(data);
                        //save string to DB
                    }
    

    and the if i need it as an image:

                Image tmp = new Image();
                var bytes = "the Byte[]"
                tmp.Source = ImageSource.FromStream(() => new MemoryStream(bytes));
    
  • wajwaj USMember ✭✭

    It says Tsak does not contain a definition for CopyTo.

  • olid4olid4 DEMember ✭✭
    edited April 2017

    @waj
    You need to put 'await' in the first line like this:
    var img = **await** mySignPad.GetImageStreamAsync(SignatureImageFormat.Png);

    Because GetImageStreamAsync(SignatureImageFormat.Png) returns a "Task".

  • olid4olid4 DEMember ✭✭

    @waj
    You just need 'await' in the first line, then it should work.
    var img = await mySignPad.GetImageStreamAsync(SignatureImageFormat.Png);

  • Neeraj_KumarNeeraj_Kumar Member ✭✭

    Can we use without await or async because it crash if i used await and async on method?.

  • JoeHarvey_MSFTJoeHarvey_MSFT Member, Xamarin Team Xamurai

    if your method isn't an async method, then no you cannot use await
    so you have a couple options to fix this.
    one would be to wrap your function in a Task.Run

    As so

            Task.Run(async () =>
                {
                    var img = await mySignPad.GetImageStreamAsync(SignatureImageFormat.Png);
                    var signatureMemoryStream = new MemoryStream();
                    img.CopyTo(signatureMemoryStream);
                    byte[] data = signatureMemoryStream.ToArray();
                });
    

    now this gets you the data, but you wont be able to return to your calling thread form here, so you'll want to handle that data in some way. Maybe by calling another method or raising an event.

Sign In or Register to comment.