0

I've been struggling with this implementation for a few hours now and can't seem to find any solutions wherever I look (SO, Xamarin Forums, Google etc)...

In this current scenario I have a few images in .Droid.Resources.Drawable which I wish to access and convert into a byte[] from my shared code. This is due to the fact that I wish to test the full span of my CRUD functionality on a REST API I've set up as an end-point for our server.

The images show up fine in the application, but for some reason I simply can't seem to warp my head around the process of converting these images to a byte[] in Xamarin. I've done it countless times in 'normal' C#...

Sorry if the code is a bit messy, but I'm sure you get the idea.

  1. I want to get an image from .Droid storage (will be ported for iOS later)
  2. Convert said image into a byte[]
  3. Send that byte[] representation to my API.

In the code's current state I'm getting this error:

C#: An instance of an abstract class can not be created

Where I'm attempting to create a new Stream (new Stream(sauce))


The below example is based on snippets found here and full credit goes to Sten and Vincent.

   /*
    * Takes an arbitrary string as a token, updates a record with dummy data and a placeholder_image.
    */
    public async Task<string> PostUpdateFoundation(string arbitrary, Image img)
    {

        ImageSource sauce = ImageSource.FromFile("abc.png");
        byte[] byte_img = FromStreamToByte(new Stream(sauce)); //error occurs here
        Debug.WriteLine("I'm in!");
        var client = new System.Net.Http.HttpClient();
        client.DefaultRequestHeaders.Add("Accept", "application/json");

        var content = new StringContent(arbitrary);
        var response = await client.PostAsync(String.Format("http://some.api.to.test.com?s={0}&img={1}", arbitrary, byte_img), content); 
        var result = response.Content.ReadAsStringAsync().Result; 
        return result;

    }
   /*
    * Attempts to convert an stream (based on image source) into a byte[].
    */
    public static byte[] FromStreamToByte (Stream input)
    {
        using (MemoryStream ms = new MemoryStream())
        {
            input.CopyTo(ms);
            return ms.ToArray();
        }
    }
PEHLAJ
  • 9,980
  • 9
  • 41
  • 53
geostocker
  • 1,190
  • 2
  • 17
  • 29
  • And what or where is the error according to you? – Gerald Versluis Apr 12 '17 at 10:23
  • Right, sorry for missing that. Just getting so damn confused by all this. In the code's current state I'm getting a "C#: An instance of an abstract class can not be created" error on the line where I'm attempting to create a `new Stream(sauce)`. – geostocker Apr 12 '17 at 10:24
  • Why are you trying to include a byte array as a query string parameter? What would you expect that to do? You're effectively calling `ToString()` on a `byte[]`, which is *really* not going to be what you want. I suspect you want your image data to be in the body of the request, either as binary data or (if you need text as well) as base64. – Jon Skeet Apr 12 '17 at 10:25
  • Why bother creating an `ImageSource` at all? Why not just create a `FileStream` to read the file? – Jon Skeet Apr 12 '17 at 10:26
  • I was thinking about that, but it would seem as if Xamarin doesn't have a `FileStream` implementation. Either that or my current version doesn't have one. – geostocker Apr 12 '17 at 10:27
  • Actually it does in the platform specific projects. So you will need the DependencyService, had about the same question some time ago; https://stackoverflow.com/questions/43341155/xamarin-forms-open-file-as-stream/43342504#43342504 – Gerald Versluis Apr 12 '17 at 10:31

1 Answers1

1

Try using Plugin.Media

            byte BImageSource = ReadFully(file.GetStream());
            var bytes = new byte[file.GetStream().Length]; //file is from the plugin and contains your image
            file.GetStream().Position = 0;
            file.GetStream().Read(bytes, 0, (int)file.GetStream().Length);
            BImageSource = ReadFully(file.GetStream()); //BImageSource is your resource in bytes

    byte[] ReadFully(Stream input)
    {
        using (MemoryStream ms = new MemoryStream())
        {
            input.CopyTo(ms);
            return ms.ToArray();
        }
    }

Hope this helps!

Ingenator
  • 222
  • 3
  • 9