Download image from the site in .NET/C#

C#.NetImageStreaming

C# Problem Overview


I am trying to download images from the site. The code which I am using is working fine while the image is available. If the image it not available it is creating a problem. How to validate availability of the image?

Code:

Method 1:

WebRequest requestPic = WebRequest.Create(imageUrl);

WebResponse responsePic = requestPic.GetResponse();

Image webImage = Image.FromStream(responsePic.GetResponseStream()); // Error

webImage.Save("D:\\Images\\Book\\" + fileName + ".jpg");

Method 2:

WebClient client = new WebClient();
Stream stream = client.OpenRead(imageUrl);

bitmap = new Bitmap(stream); // Error : Parameter is not valid.
stream.Flush();
stream.Close();
client.dispose();

if (bitmap != null)
{
    bitmap.Save("D:\\Images\\" + fileName + ".jpg");
}

Edit:

Stream has the following statements:

      Length  '((System.Net.ConnectStream)(str)).Length' threw an exception of type  'System.NotSupportedException'    long {System.NotSupportedException}
    Position  '((System.Net.ConnectStream)(str)).Position' threw an exception of type 'System.NotSupportedException'    long {System.NotSupportedException}
 ReadTimeout  300000    int
WriteTimeout  300000    int

C# Solutions


Solution 1 - C#

There is no need to involve any image classes, you can simply call WebClient.DownloadFile:

string localFilename = @"c:\localpath\tofile.jpg";
using(WebClient client = new WebClient())
{
    client.DownloadFile("http://www.example.com/image.jpg", localFilename);
}

Update
Since you will want to check whether the file exists and download the file if it does, it's better to do this within the same request. So here is a method that will do that:

private static void DownloadRemoteImageFile(string uri, string fileName)
{
    HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri);
    HttpWebResponse response = (HttpWebResponse)request.GetResponse();

    // Check that the remote file was found. The ContentType
    // check is performed since a request for a non-existent
    // image file might be redirected to a 404-page, which would
    // yield the StatusCode "OK", even though the image was not
    // found.
    if ((response.StatusCode == HttpStatusCode.OK || 
        response.StatusCode == HttpStatusCode.Moved || 
        response.StatusCode == HttpStatusCode.Redirect) &&
        response.ContentType.StartsWith("image",StringComparison.OrdinalIgnoreCase))
    {

        // if the remote file was found, download oit
        using (Stream inputStream = response.GetResponseStream())
        using (Stream outputStream = File.OpenWrite(fileName))
        {
            byte[] buffer = new byte[4096];
            int bytesRead;
            do
            {
                bytesRead = inputStream.Read(buffer, 0, buffer.Length);
                outputStream.Write(buffer, 0, bytesRead);
            } while (bytesRead != 0);
        }
    }
}

In brief, it makes a request for the file, verifies that the response code is one of OK, Moved or Redirect and also that the ContentType is an image. If those conditions are true, the file is downloaded.

Solution 2 - C#

I have used Fredrik's code above in a project with some slight modifications, thought I'd share:

private static bool DownloadRemoteImageFile(string uri, string fileName)
{
	HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri);
	HttpWebResponse response;
	try
	{
		response = (HttpWebResponse)request.GetResponse();
	}
	catch (Exception)
	{
		return false;
	}

	// Check that the remote file was found. The ContentType
	// check is performed since a request for a non-existent
	// image file might be redirected to a 404-page, which would
	// yield the StatusCode "OK", even though the image was not
	// found.
	if ((response.StatusCode == HttpStatusCode.OK ||
		response.StatusCode == HttpStatusCode.Moved ||
		response.StatusCode == HttpStatusCode.Redirect) &&
		response.ContentType.StartsWith("image", StringComparison.OrdinalIgnoreCase))
	{

		// if the remote file was found, download it
		using (Stream inputStream = response.GetResponseStream())
		using (Stream outputStream = File.OpenWrite(fileName))
		{
			byte[] buffer = new byte[4096];
			int bytesRead;
			do
			{
				bytesRead = inputStream.Read(buffer, 0, buffer.Length);
				outputStream.Write(buffer, 0, bytesRead);
			} while (bytesRead != 0);
		}
		return true;
	}
	else
		return false;
}

Main changes are:

  • using a try/catch for the GetResponse() as I was running into an exception when the remote file returned 404
  • returning a boolean

Solution 3 - C#

Also possible to use DownloadData method

    private byte[] GetImage(string iconPath)
    {
        using (WebClient client = new WebClient())
        {
            byte[] pic = client.DownloadData(iconPath);
            //string checkPath = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) +@"\1.png";
            //File.WriteAllBytes(checkPath, pic);
            return pic;
        }
    }

Solution 4 - C#

        private static void DownloadRemoteImageFile(string uri, string fileName)
        {
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri);
            HttpWebResponse response = (HttpWebResponse)request.GetResponse();

            if ((response.StatusCode == HttpStatusCode.OK ||
                response.StatusCode == HttpStatusCode.Moved ||
                response.StatusCode == HttpStatusCode.Redirect) &&
                response.ContentType.StartsWith("image", StringComparison.OrdinalIgnoreCase)) 
            {
                using (Stream inputStream = response.GetResponseStream())
                using (Stream outputStream = File.OpenWrite(fileName))
                {
                    byte[] buffer = new byte[4096];
                    int bytesRead;
                    do
                    {
                        bytesRead = inputStream.Read(buffer, 0, buffer.Length);
                        outputStream.Write(buffer, 0, bytesRead);
                    } while (bytesRead != 0);
                }
            }
        }

Solution 5 - C#

The best practice to download an image from Server or from Website and store it locally.

WebClient client=new Webclient();
client.DownloadFile("WebSite URL","C:\\....image.jpg");
client.Dispose();

Solution 6 - C#

You can use this code

using (WebClient client = new WebClient()) {
					Stream stream = client.OpenRead(imgUrl);
					if (stream != null) {
						Bitmap bitmap = new Bitmap(stream);
						ImageFormat imageFormat = ImageFormat.Jpeg;
						if (bitmap.RawFormat.Equals(ImageFormat.Png)) {
							imageFormat = ImageFormat.Png;
						}
						else if (bitmap.RawFormat.Equals(ImageFormat.Bmp)) {
							imageFormat = ImageFormat.Bmp;
						}
						else if (bitmap.RawFormat.Equals(ImageFormat.Gif)) {
							imageFormat = ImageFormat.Gif;
						}
						else if (bitmap.RawFormat.Equals(ImageFormat.Tiff)) {
							imageFormat = ImageFormat.Tiff;
						}

						bitmap.Save(fileName, imageFormat);
						stream.Flush();
						stream.Close();
						client.Dispose();
					}
				}

Project available at: github

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionGeethView Question on Stackoverflow
Solution 1 - C#Fredrik MörkView Answer on Stackoverflow
Solution 2 - C#germankiwiView Answer on Stackoverflow
Solution 3 - C#Alexander NikolaevView Answer on Stackoverflow
Solution 4 - C#CodeNinjaView Answer on Stackoverflow
Solution 5 - C#Mohamad-Al-IbrahimView Answer on Stackoverflow
Solution 6 - C#Ranjit SinghView Answer on Stackoverflow