Descargar la imagen del sitio en .NET / C #

Estoy tratando de descargar imágenes del sitio. El código que estoy usando funciona bien mientras la imagen está disponible. Si la imagen no está disponible, está creando un problema. ¿Cómo validar la disponibilidad de la imagen?

Código:

Método 1:

WebRequest requestPic = WebRequest.Create(imageUrl); WebResponse responsePic = requestPic.GetResponse(); Image webImage = Image.FromStream(responsePic.GetResponseStream()); // Error webImage.Save("D:\\Images\\Book\\" + fileName + ".jpg"); 

Método 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"); } 

Editar:

Stream tiene las siguientes declaraciones:

  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 

No es necesario involucrar ninguna clase de imagen, simplemente puede llamar a WebClient.DownloadFile :

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

Actualizar
Como querrá verificar si el archivo existe y descargar el archivo si lo hace, es mejor hacerlo dentro de la misma solicitud. Así que aquí hay un método que hará eso:

 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); } } } 

En resumen, realiza una solicitud para el archivo, verifica que el código de respuesta sea uno de OK , Moved o Redirect y también que ContentType es una imagen. Si esas condiciones son verdaderas, el archivo se descarga.

He usado el código de Fredrik arriba en un proyecto con algunas pequeñas modificaciones, pensé que compartiría:

 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; } 

Los principales cambios son:

  • utilizando un try / catch para el GetResponse () ya que estaba ejecutando una excepción cuando el archivo remoto devolvió 404
  • devolviendo un booleano

También es posible utilizar el método DownloadData

  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; } } 
  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); } } }