method headers examples example downloaddata dotnetperls c# asp.net webclient

headers - webclient get c#



El uso de WebClient para obtener imágenes remotas produce GIF granulosos y no puede manejar PNG+BMP (1)

Algunos puntos sobre su método GetImage:

  • Cuando utiliza Image.FromStream, no debe cerrar (o eliminar) la transmisión
  • Si llamas a Dispose en una transmisión (con la instrucción using) no necesitas llamar a Close
  • Está escribiendo en la transmisión, pero luego no "rebobinando", así que l_image no obtiene ningún dato por lo que puedo ver (a menos que Image.FromStream restablezca la posición). (Podría ser que los decodificadores gif / jpg rebobinan la secuencia pero bmp / ​​png no, de ahí el error).
  • ¿Por qué no utiliza el constructor MemoryStream que toma una matriz de bytes?

En resumen, creo que su método GetImage puede ser reemplazado por:

private Image GetImage(string filePath) { WebClient l_WebClient = new WebClient(); byte[] l_imageBytes = l_WebClient.DownloadData(filePath); MemoryStream l_stream = new MemoryStream(l_imageBytes); return Image.FromStream(l_stream); }

Ahora, más importante, ¿por qué estás cargando la imagen? ¿Por qué no solo sirve el archivo como respuesta, configurando el tipo de contenido como ya lo está haciendo, o posiblemente solo basado en la extensión? En otras palabras, todo su código se convertiría en:

protected void Page_Load(object sender, EventArgs e) { string filePath = Request.QueryString["i"]; string extension = l_filePath.Substring(l_filePath.LastIndexOf(''.'') + 1); Response.ContentType = "image/" + extension; byte[] data = new WebClient.DownloadData(filePath); Response.OutputStream.Write(data, 0, data.Length); Response.End(); }

Un poco más de manejo de errores (incluyendo "¿es esta una extensión razonable?") Sería bueno, pero aparte de eso, creo que está bien. El único beneficio de cargar la imagen usted mismo es que puede validar que realmente es una imagen en lugar de un virus o algo así.

EDITAR: solo por interés, ¿tienes una buena razón por la que deseas que las solicitudes de imágenes pasen por tu servidor? ¿Por qué escribiría el autor de la página web?

<img src="http://www.mydomain.com/ImageLoader.aspx?i=http://images.mydomain.com/img/a.jpg" />

en lugar de

<img src="http://images.mydomain.com/img/a.jpg" />

Hay algunas razones por las que podría ser útil, pero en muchos casos es solo un desperdicio.

¡Saludos!

Estoy creando un prototipo de formulario web (ImageLaoder.aspx) que devolverá una imagen para que pueda usarse como este ejemplo simple en otras páginas web / formularios web:

<img src="http://www.mydomain.com/ImageLoader.aspx?i=http://images.mydomain.com/img/a.jpg" />

Hasta ahora, carga JPG sin problemas, sin embargo, los GIF se ven "granulosos" en comparación con los orignals, y las BMP y PNG dan como resultado la siguiente excepción:

System.Runtime.InteropServices.ExternalException: se ha producido un error genérico en GDI +

Mi código hasta ahora se ve así:

protected void Page_Load(object sender, EventArgs e) { string l_filePath = Request.QueryString["i"]; System.Drawing.Image l_image = GetImage(l_filePath); if (l_image != null) { System.Drawing.Imaging.ImageFormat l_imageFormat = DetermineImageFormat(l_filePath); WriteImageAsReponse(l_image, l_imageFormat); } } private System.Drawing.Image GetImage(string filePath) { WebClient l_WebClient = new WebClient(); byte[] l_imageBytes = l_WebClient.DownloadData(filePath); System.Drawing.Image l_image = null; using (MemoryStream l_MemStream = new MemoryStream(l_imageBytes, 0, l_imageBytes.Length)) { l_MemStream.Write(l_imageBytes, 0, l_imageBytes.Length); l_image = System.Drawing.Image.FromStream(l_MemStream, true); l_MemStream.Close(); } return l_image; } private System.Drawing.Imaging.ImageFormat DetermineImageFormat(string filePath) { if (filePath.EndsWith(".jpg", StringComparison.OrdinalIgnoreCase)) return System.Drawing.Imaging.ImageFormat.Jpeg; else if (filePath.EndsWith(".gif", StringComparison.OrdinalIgnoreCase)) return System.Drawing.Imaging.ImageFormat.Gif; else if (filePath.EndsWith(".png", StringComparison.OrdinalIgnoreCase)) return System.Drawing.Imaging.ImageFormat.Png; else return System.Drawing.Imaging.ImageFormat.Bmp; } private void WriteImageAsReponse(System.Drawing.Image image, System.Drawing.Imaging.ImageFormat imageFormat) { if (image == null) return; System.Drawing.Bitmap l_outputBitMap = new Bitmap(image); if (imageFormat == System.Drawing.Imaging.ImageFormat.Jpeg) Response.ContentType = "image/jpg"; else if (imageFormat == System.Drawing.Imaging.ImageFormat.Gif) Response.ContentType = "image/gif"; else if (imageFormat == System.Drawing.Imaging.ImageFormat.Png) Response.ContentType = "image/png"; else Response.ContentType = "image/bmp"; l_outputBitMap.Save(Response.OutputStream, imageFormat); }

¿Alguna idea de por qué los GIF son granulados y los PNG y las BMP causan excepciones?