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?
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);
Related
I was looking into this document
AutoDesk
I am able to get Files/Folders structure and content from BIM 360 but is there a way I can read the content of a file as file stream to write it in different file(I don't want to download the file locally) in .Net core without using rest end point.
The getObject method (from the official Forge SDK) that is typically used to access OSS data (which BIM 360 Docs uses under the hood as well) does return System.IO.Stream already. So you should be able to stream the incoming data anywhere you need. For example, you can redirect the stream to another POST request as explained in this tutorial:
var request = new HttpRequestMessage(HttpMethod.Post, "/some/endpoint");
using (var requestContent = new StreamContent(stream))
{
request.Content = requestContent;
using (var response = await _httpClient.SendAsync(request, HttpCompletionOption.ResponseHeadersRead))
{
response.EnsureSuccessStatusCode();
var content = await response.Content.ReadAsStreamAsync();
}
}
I'm using Refit in my C# application to interact with a REST API, and the API method has a call that returns a .jpg image. I want to download this image using Refit and get it as a byte array, but it seems to return a garbled string. See below. See below interface method for downloading of the image
[Get("/Photos/{id}")]
Task<string> DownloadPhoto(Guid id);
I tried parsing the string as a Base64 string but that didn't work, so I presume it's not that. Any ideas?
EDIT: First line of garbled response here. Note if going to this same URL in a browser it works fine and displays the image
����\0\u0010JFIF\0\u0001\u0001\0\0H\0H\0\0��\0XExif\0\0MM\0*\0\0\0\b\0\u0002\u0001\u0012\0\u0003\0\0\0\u0001\0\u0001\0\0�i\0\u0004\0\0\0\u0001\0\0\0&\0\0\0\0\0\u0003�\u0001\0\u0003\0\0\0\u0001\0\u0001\0\0�\u0002\0\u0004\0\0\0\u0001\0\0\u0002X�\u0003\0\u0004\0\0\0\u0001\0\0\u0003 \0\0\0\0��\08Photoshop 3.0\08BIM\u0004\u0004\0\0\0\0\0\08BIM\u0004%\0\0\0\0\0\u0010�\u001d�ُ\0�\u0004�\t���B~��\0\u0011\b\u0003 \u0002X\u0003\u0001\"\0\u0002\u0011\u0001\u0003\u0011\u0001��\0\u001f
What worked for me was to have the method declared as returning
Task<HttpContent> and then you can retrieve the data from the returned HttpContent instance in a variety of manners.
For example:
Task<HttpContent> DownloadPhoto(Guid id);
And then:
HttpContent content = await DownloadPhoto(guid);
byte[] bytes = await content.ReadAsByteArrayAsync();
you can get the byte array using refit as in the example below
[Get("/Photos/{id}")]
Task<HttpResponseMessage> DownloadPhoto(Guid id);
and then you can get the byte array from
var Response = await YourRefitClient.DownloadPhoto(id);
byte[] ByteArray = await Response.Content.ReadAsByteArrayAsync();
I'm working on an MVC webapplication that streams data from many resources.
My problem is when want to get data (music file) from a stream resource and then stream it to my web page, I don't know how not to download completely and then stream it to my web page.
Here is my webapi code:
[HttpGet]
public HttpResponseMessage Downlaod(int Data)
{
WebClient myWebClient = new WebClient();
Uri u =new Uri("https://api.soundcloud.com/tracks/" + Data + "/stream?client_id=*******************");
byte[] myDataBuffer = myWebClient.DownloadData(u);
MemoryStream st = new MemoryStream(myDataBuffer);
/*heres when i download data and convert it to memory stream*/
HttpResponseMessage result = new HttpResponseMessage(HttpStatusCode.OK);
result.Headers.AcceptRanges.Add("bytes");
result.StatusCode = HttpStatusCode.OK;
result.Content = new StreamContent(st);
result.Content.Headers.ContentLength = st.Length;
result.Content.Headers.ContentType =
new MediaTypeHeaderValue("application/octet-stream");
return result;
}
I want to stream immediately when I receive bytes from my resource.
note: I'm not asking about how to stream data to the client it's about streaming from server to server.
I want to get file from another server and stream it to my clients without downloading the full content before start streaming.
note2: I also don't want to download the full content in once because the full content is very big, I want to get a byte from my content and then send that byte to the client not downloading the full content.
I think I'm doing it in wrong way and it is not possible with an MVC application if anyone can introduce an application that can proxy bytes from destination to client it would be the answer. the main reason that I want this,is to proxy a music file from my content server to a javascript music player and not to expose the main file.
My goal is to read a jpg file from a ashx Url. I would like to do this with Windows Phone 8 but I'm starting with .Net 4.5 because that might be more simple for me.
Here is an example url:
http://gatherer.wizards.com/Handlers/Image.ashx?multiverseid=239959&type=card
If you go to this Url in IE 10 you'll see an image. How do I download the image in .Net 4.5? I have tried using:
HttpClient httpClient = new HttpClient();
httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("image/jpg"));
string resourceAddress = "http://gatherer.wizards.com/Handlers/Image.ashx?multiverseid=239959&type=card";
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, resourceAddress);
HttpResponseMessage response = await httpClient.SendAsync(request, HttpCompletionOption.ResponseContentRead);
byte[] responseBytes = await response.Content.ReadAsByteArrayAsync();
and also using WebClient
string url = #"http://gatherer.wizards.com/Handlers/Image.ashx?multiverseid=220041&type=card";
byte[] imageData;
using (WebClient client = new WebClient())
{
imageData = client.DownloadData(new Uri(url));
}
both of these methods return no data. How do I get the data and format it into a jpg? I am pretty new to using ashx files. I see that they are used easily in Asp.Net web sites but have not been able to find anything that allows to simply download the file. The goal is to download the jpg file and display it in a windows phone 8 application.
Take a look at that URL. You've URL encoded the &, so indeed there's nothing returned from
http://gatherer.wizards.com/Handlers/Image.ashx?multiverseid=220041&type=card
this
http://gatherer.wizards.com/Handlers/Image.ashx?multiverseid=220041&type=card
however, worked just fine for me in Windows 8 using your first code sample.
By the way, I see you set an Accept header of image/jpg, the ASHX seems to set the Content-type to image/jpeg - it does work though.
I am accessing an API that returns a favicon for a specified domain (http://getfavicon.appspot.com/). I have a long list of domains that I want to get Icons for and don't want to make the call to the web service every time, so I figured I would get the response and store the image either on the file system or in a DB Blob.
However. I don't know how to get something meaningful from the response stream that comes back from the service.
byte[] buf = new byte[8192];
var request = (HttpWebRequest)WebRequest.Create("http://getfavicon.appspot.com/http://stackoverflow.com");
var response = (HttpWebResponse)request.GetResponse();
var resStream = response.GetResponseStream();
I've got as far as here to get a response back, but how would I can I treat this as something I can save to a SQL DB or out to the filesystem?
Am I missing something simple?
Thanks
If you use the System.Net.WebClient class, you can do this a little easier.
This will download the URL and save it to a local file:
var client = new System.Net.WebClient();
client.DownloadFile(
// Url to download
#"http://getfavicon.appspot.com/http://stackoverflow.com",
// Filename of where to save the downloaded content
"stackoverflow.com.ico");
If you want a byte[] instead, use the DownloadData method.