How to convert Image URL to ImageStream ? - c#

I was doing this for local image
var imgstream = System.IO.File.OpenRead(#"C:\Users\TheSarfaraz\Downloads\SampleFacebookApp\SampleFacebookApp\SampleFacebookApp\Content\images\dreams-facebook-cover_4173.jpg");
But its not letting me do this for image URL
If I try this
var imgstream = System.IO.File.OpenRead(#"http://www.trendycovers.com/covers/Listen_to_your_heart_facebook_cover_1330517429.jpg?i");
I'm getting this error
URI formats are not supported.
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Exception Details: System.ArgumentException: URI formats are not supported.

You can't ask for a web resource, such as image, to be treated as a regular file and to use I/O operations, such as FileStream, on it.
In your case, you should use the WebClient class which is using the HTTP GET method in order to download the image properly.
For example:
using (WebClient Client = new WebClient ())
{
Client.DownloadFile(#"http://www.trendycovers.com/covers/Listen_to_your_heart_facebook_cover_1330517429.jpg?i", "Listen_to_your_heart_facebook_cover_1330517429.jpg");
}
The image file will be downloaded to your application folder unless you declare absolute path in the second parameter (fileName), such as: c:\images\Listen_to_your_heart_facebook_cover_1330517429.jpg

You are using the wrong class. You can not read a file from a webserver with the File.OpenRead function because this is not designed for that purpose. Try the WebClient.OpenRead function instead.

Related

How does the UploadObjectAsync() method work?

https://forge.autodesk.com/en/docs/bim360/v1/tutorials/documen-management/upload-document/
I am following the tutorial above to upload a file into a BIM 360 folder through Autodesk Forge. I have reached Step 6: Upload the File to the Storage Object and I am trying to use the method UploadObjectAsync() to upload a file but I am getting an error stating: error getting value from 'ReadTimeout' on 'System.Web.HttpInputStream' and I am unsure how to fix this.
Am I using the wrong method or there something I am missing in the code? Below is the method I am using on .NET.
HttpPostedFile file = req.Files[0];
ObjectsApi objectsApi = new ObjectsApi();
dynamic objects = await objectsApi.UploadObjectAsync(bucketKey, objectName, file.ContentLength, file.InputStream);
Try use the underlying stream of a StreamReader from the file to upload, instead of the raw InputStream from multipart form:
using (StreamReader streamReader = new StreamReader(fileSavePath))
{
await objects.UploadObjectAsync(bucketKey, objectName,(int)streamReader.BaseStream.Length, streamReader.BaseStream, "application/octet-stream");
...
}
Given how the UploadObjectAsync and its chained method UploadObjectAsyncWith(code here) is implemented you'd better saved the posted file and then upload it instead of piping streams. See an example here.

BitmapFrame - No imaging component suitable to complete this operation was found [duplicate]

I'm downloading in image from web to save it locally. It works great with any other image formats but it this method below fails with an argument exception when I try to read a WebP image.
private static Image GetImage(string url)
{
try
{
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(url);
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
return Image.FromStream(response.GetResponseStream());
}
catch
{
return null;
}
}
How do you read .webp images in C#?
I found this other question that allows for converting between types but I do not want to do that WebP library for C#
Reason I'm not wanting to do it is because I think it might lose some quality. Besides, I want to know why is this not working.
The base class libraries won't help you to deal with WebP images. However, if you only want to save the received file to the disk, you don't have to even know that you are dealing with a WebP images. You can simply treat the received data as a binary blob and dump it to a file, for example using Stream.CopyTo and a FileStream.
The Content-Type HTTP header will give you the mime type of the file you're downloading, and the Content-Disposition header can provide you with a filename and extension (though you might have to do some parsing). You can access those using HttpWebResponse.ContentType and HttpWebResponse.Headers["Content-Disposition"].
#Trillian nailed it. Here is a code snippet for what I did based on his suggestion. Wanted to add code so not posting this as a comment.
To get just the image file extension, you can do this
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(url);
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
string fileExt = response.ContentType.Replace("image/", string.Empty);
To get the file name with extension, you can do the following and the do parsing like I did above. It just has some more data in it.
response.Headers["Content-Disposition"];
Once you have you file name you want to save as, create a file stream and copy the response stream into it.
FileStream fs = new FileStream(targetPath + fileName, FileMode.Create);
response.GetResponseStream().CopyTo(fs);
Assuming you app has access to the destination, image should get saved. Make sure to add try catch and handle exceptions properly. Also note that FileMode.Create will overwrite if the file already exists!

Parameter is not valid Exception in creating new Bitmap in C#?

We have a method to save an image as corrected format as the following :
public static string SaveImageAsCorrectFormat(string tempFilePath, string newFileName, string destinationDirectoryPath)
{
using (Image image = new Bitmap(tempFilePath))// Exception : Parameter is not valid.
{
string extension = image.RawFormat.GetExtension();
string newAbsoluteFilePath = Path.Combine(destinationDirectoryPath, string.Format("{0}.{1}", newFileName, extension));
image.Save(newAbsoluteFilePath, image.RawFormat);
return newAbsoluteFilePath;
}
}
but in in the following line an exception has occurred :
//Parameter is not valid.
using (Image image = new Bitmap(tempFilePath))
I changed it to the following but Out of memory has occurred :
// Out of memory
using (Bitmap image = (Bitmap)Image.FromFile(tempFilePath))
The image size is 10KB and 10GB of RAM is free.
What's the problem?
P.S:
I don't have the problem in local. But when I publish the software on server this problem occur.
Edit:
I'm using windows Server 2012 R2 and IIS 8.5.9600.16384. The Application (website) has full control on IIS_IUSRS and IUSR.
I think the problem isn't related to permission, because I could open the file with the following code :
using (FileStream fileStream = File.Open(tempFilePath, FileMode.Open)) // OK
using (Image image = new Bitmap(fileStream))// Exception : Parameter is not valid.
Solution:
I changed website application pool identity to Local System and it's OK now, Is it OK to change application pool identity or it is a security hole ?
It appears that the image is corrupted, or maybe just has the wrong file extension.
If the extension is jpeg, .NET will attempt to decode it as a JPEG. Note that this behaviour differs from browsers: browsers tend to look at the content of the file and decide its format based on that; due to this, you could be under the misconception that a jpeg file is fine because it displays in the browser, when in reality it contains a PNG image.
If you open the image file in Firefox, the window titlebar tells you what the real file format is independent of its file extension.
You have to grant permission to the folder you are trying to access through your web application. If you are using cPanel check here.
Late in the day but I could not find a reliable workaround. Sometimes environmental issues will affect operation. In my case I retried the action a number of times if an exception occurred. If you take this approach your action should succeed but make sure the action is idempotent.
e.g. in C#
Action action = () => { //call SaveImageAsCorrectFormat }
try {
action();
}
catch
{
try {
action();
catch (Exception exception) {
//handle
}
}

How to tell if Image.FromStream is complete

i have the following code:
var request = (HttpWebRequest)HttpWebRequest.Create(url);
var response = request.GetResponse();
var stream = response.GetResponseStream();
if (stream != null) {
Image newImage = Image.FromStream(stream, true);
pic.Thumb = newImage.ImageToByteArray();
}
What happens if the read times out? Or the connection is aborted mid-download?
The docs say that it will throw an ArgumentException if it's not a valid format or is null, but I have no idea if it will throw that exception if the image is only partially downloaded.
Unfortunately, I can't rely on the ContentLength header to tell me the proper size of the file, because the server lies and gives a larger content length than the file actually is. So my hope is that Image.FromStream will be able to tell if the image is complete or not.
Can anyone provide some insight here?
Note: ImageToByteArray is just an extension method that uses a memory stream to convert the Image to a byte[]
UPDATE:
According to Darin, then an ExternalException gets thrown when you try to save the image. However, my own testing in which I truncated an image file shows that FromStream does in fact throw an ArgumentException if the image is not the correct number of bytes.
What happens if the read times out?
An exception will be thrown before entering the if condition.
Or the connection is aborted?
An exception will be thrown before entering the if condition.
but I have no idea if it will throw that exception if the image is only partially downloaded.
An image cannot be partially downloaded. The GetResponseStream is a blocking method meaning that either you get everything, or an exception (or of course in your case you could also get an exception if what you fetched is not an image but some HTML page which will happen when you try to instantiate the Image GDI+ object).
As a side note, to avoid leaking, you probably also want to wrap this Image disposable resource into a using statement.

How to download a file without extension in C#

Okay so I want to download a file from a website, but the file is lacking an extension.
(it's an image file, I know this much, but the link does not provide the actual extension)
When I use webrequest, or webclient to download the file I get a "404 file not found" exception.
WebClient wc = new WebClient();
Stream strm = wc.DownloadFile("http://some_site.some_domain/some_image.","C:/some_directory/save_name.some_extention");
Notice the lack of extention at the end of the URL.
The site in question displays the image fine in a webbrowser, but when viewing just the image there is no extension and thus it's treated an unknown file (not showing an image).
So simply put: how do I download a file if there is no extention specified?
Thanks in advance!
So you're trying to determine what extension to give the file after downloading? If the URL doesn't have one you would have to inspect the actual data of the file.
You might be able to inspect the beginning of the file and see if it matches known valid file types. For instance, PNGs seem to have 'PNG' as bytes 2-4 (at least in the ones I've inspected). By looking at that data you should be able to determine the format with a fairly high accuracy.
This would be my best suggestion, if this doesn't work I don't know how to solve you problem...
List<string> fileExtensions = new List<string>(){"png","gif","bmp","jpg"}// other known image file extensions here...
WebClient wc = new WebClient();
foreach(var extension in fileExtensions)
{
try
{ wc.DownloadFile("http://some_site.some_domain/some_image."+extension,"C:/some_directory/save_name."+extension);
break;
}
catch {}
}
This would just be a work around, I guess... Not a real solution...

Categories

Resources