1

I am adding features to a Windows Phone 8.1 RT app, built using MVVM. I need to be able to download an Image to the device and save/ display it. I can already do this with images from a fixed URL.

We have an accompanying website and API to go with the app. The way it works is the app sends a request to the API to get a download code for the image in question, and then sends this code along with the ID of the document in a request to the website, which verifies the user has access to the document and should then serve up the image if successful. The API and website are already in use with the iOS and Android equivalents of the app, so I know they work.

To retrieve the image, I'm trying to use HttpClient. This is my current code, which is getting a response from the server, with some content and the filename of the image (which look to be correct):

Uri uri = new Uri("<website address>");

Dictionary<string, string> pairs = new Dictionary<string, string>();                
pairs.Add("RequestToken", response.DownloadToken);
pairs.Add("DocumentID", "<doc ID>");

HttpFormUrlEncodedContent formContent = new HttpFormUrlEncodedContent(pairs);                             

HttpClient client = new HttpClient();
HttpResponseMessage response2 = await client.PostAsync(uri, formContent);

var imageContent = response2.Content.ReadAsInputStreamAsync();

I'm trying to write the content to a stream, then convert that to a BitmapImage object, which I can then save to the device and display to the user. It's the conversion I'm struggling with. My plan is to convert the InputStream to a bytearray, then convert that to a Bitmap. The problem is, I can't find any extension methods in 8.1 which will do this, and very little in the way of documentation to help.

Can anyone point me in the right direction here? Maybe there's a better way of doing a conversion from HttpResponseMessage.Content to BitmapImage?

odinel
  • 566
  • 1
  • 5
  • 28
  • Why not convert the stream to a byte array and then convert the byte array to a bitmap image? – Pseudonym Jan 06 '16 at 16:48
  • That's what I'm trying to do, but I can't figure it out in 8.1, unfortunately – odinel Jan 06 '16 at 16:49
  • https://stackoverflow.com/questions/7669311/is-there-a-way-to-convert-a-system-io-stream-to-a-windows-storage-streams-irando – Pseudonym Jan 06 '16 at 16:55
  • Thanks for the link. I've actually read that answer many times today (it's the top Google result for many of the terms I tried), but I haven't been able to find what I need from it. For example, the accepted answer suggests creating a .NET Stream object, then using the HttpClient.GetStreamAsync method. But GetStreamAsync isn't available to me... I'm assuming it's an 8.0 method, unless I'm missing a namespace? I've tried much Googling to find out how to convert IInputStream to a byte array, but haven't yet found a solution that works – odinel Jan 06 '16 at 17:12
  • Is your app based on Silverlight, or Win RT? – Rowland Shaw Jan 06 '16 at 17:13

1 Answers1

3

Make sure you are importing the right HttpClient:

using Windows.Web.Http;

And import other necessary namespaces:

using Windows.Storage.Streams;
using Windows.UI.Xaml.Media.Imaging;

Then, as you wrote in your qurestion, get the IInputStream, but make sure to use await with ReadAsInputStreamAsync():

HttpClient client = new HttpClient();
HttpResponseMessage response = await client.PostAsync(uri, formContent);

// Do not forget to use an 'await'.
IInputStream imageStream = await response.Content.ReadAsInputStreamAsync();

Then, copy the IInputStream into an IRandomAccessStream:

InMemoryRandomAccessStream randomAccessStream =
    new InMemoryRandomAccessStream();
await RandomAccessStream.CopyAsync(imageStream, randomAccessStream);

This is important, rewind the IRandomAccessStream:

// Rewind.
randomAccessStream.Seek(0);

Finally, create a BitmapImage and assign it to your XAML Image control:

var bitmap = new BitmapImage();
bitmap.SetSource(randomAccessStream);

MyImage.Source = bitmap;

That's all!

If you need a URI to test, try this one:

Uri uri = new Uri("http://heyhttp.org/emoji.png");
HttpResponseMessage response = await client.GetAsync(uri);
kiewic
  • 15,852
  • 13
  • 78
  • 101