Descargar imagen del sitio in.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
4 answers
No hay necesidad de involucrar a ninguna clase de imagen, simplemente puede llamar WebClient.DownloadFile
:
string localFilename = @"c:\localpath\tofile.jpg";
using(WebClient client = new WebClient())
{
client.DownloadFile("http://www.example.com/image.jpg", localFilename);
}
Update
Dado que querrá verificar si el archivo existe y descargarlo 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, se hace una solicitud para el archivo, comprueba que el código de respuesta es uno de OK
, Moved
o Redirect
y también que ContentType
es una imagen. Si esas condiciones son ciertas, el archivo se descarga.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-09-01 10:19:56
He utilizado el código de Fredrik anterior en un proyecto con algunas ligeras 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:
- usando un try / catch para GetResponse() ya que me estaba topando con una excepción cuando el archivo remoto devolvió 404
- devolviendo un booleano
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-09-27 22:44:04
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;
}
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-04-12 15:10:02
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);
}
}
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-12-05 16:10:24