2008-08-22 10 views
13

Lo que quiero lograr es esto. Quiero darle al usuario la posibilidad de cargar un archivo de imagen, almacenar la imagen en BLOB en SQL Server y luego usar esta imagen como logotipo en otras páginas del sitio.ASP de procesamiento dinámico: Imagen de la entrada BLOB en ASP.NET

he hecho esto mediante el uso de

Response.Clear(); 
    Response.ContentType = "image/pjpeg"; 
    Response.BinaryWrite(imageConents); 
    Response.End(); 

pero para hacer esto, yo uso un control de usuario en el lugar donde quiero mostrar la imagen. Quiero hacerlo si es posible usando un asp: control de imagen, o incluso un antiguo control de imagen html. es posible?

Gracias a todos

+0

Si está trabajando con System.Drawing en ASP.NET, [lea estas dificultades que debe evitar] (http://nathanaeljones.com/163/20-image-resizing-pitfalls/). Alternativamente, solo use la biblioteca [my ImageResizing.Net] (http://imageresizing.net) para evitar todos los errores de GDI, obtenga un lector de Blob SQL optimizado y un sistema de almacenamiento en caché de disco increíblemente bueno. –

+1

El siguiente artículo lo ayudará a: [Byte de vinculación automática [] a asp: Imagen] (http://www.codeproject.com/Tips/445876/Auto-bind-byte-to-asp-Image) –

Respuesta

18

Agregue un "Controlador genérico" a su proyecto web, asígnele un nombre parecido a Image.ashx. Implementarlo como esto:

public class ImageHandler : IHttpHandler 
{ 

    public void ProcessRequest(HttpContext context) 
    { 
     using(Image image = GetImage(context.Request.QueryString["ID"])) 
     {  
      context.Response.ContentType = "image/jpeg"; 
      image.Save(context.Response.OutputStream, ImageFormat.Jpeg); 
     } 
    } 

    public bool IsReusable 
    { 
     get 
     { 
      return true; 
     } 
    } 
} 

Ahora acaba de poner en práctica el método GetImage para cargar la imagen con el identificador dado, y se puede utilizar

<asp:Image runat="server" ImageUrl="~/Image.ashx?ID=myImageId" /> 

para mostrarlo. También puede pensar en implementar alguna forma de almacenamiento en caché en el controlador. Y recuerde que si desea cambiar el formato de imagen a PNG, debe usar un MemoryStream intermedio (porque los PNG requieren una secuencia de búsqueda para guardar).

+0

Sé que esto es viejo, pero creo que tienes lo que estoy buscando aquí. Solo me falta el conocimiento en este momento, para resolverlo. Tengo mi controlador escrito. Aquí está http://pastebin.com/m75e17237 y recibí la llamada a ese controlador. Se ve así: http://pastebin.com/m63e1ebc3 Pero cuando la página se carga, acabo de obtener la imagen que falta pequeña caja X roja. Nunca he usado un controlador antes, por lo que puede estar haciendo algo mal. Una cosa que noto es que si establezco un punto de interrupción en el controlador, nunca llega allí. Cualquier consejo sería increíble, si tienes la oportunidad. -tendrá – aape

+0

@aape: ¿ha registrado el controlador en web.config? –

+0

Tratando de obtener una respuesta a mi problema aquí, tengo dos imágenes que quiero mostrar en una vista dependiendo de si un estudiante está inscripto o no. Esta vista que tengo está fuertemente tipada, ¿cómo puedo hacer que funcione? – user793468

9

Puede codificar BASE64 el contenido de la imagen directamente en el atributo SRC, sin embargo, creo que solo Firefox lo analizará de nuevo en una imagen.

Lo que suelen hacer es crear un HTTPHandler muy ligero para servir las imágenes:

using System; 
using System.Web; 

namespace Example 
{ 
    public class GetImage : IHttpHandler 
    { 

     public void ProcessRequest(HttpContext context) 
     { 
      if (context.Request.QueryString("id") != null) 
      { 
       Blob = GetBlobFromDataBase(id); 
       context.Response.Clear(); 
       context.Response.ContentType = "image/pjpeg"; 
       context.Response.BinaryWrite(Blob); 
       context.Response.End(); 
      } 
     } 

     public bool IsReusable 
     { 
      get 
      { 
       return false; 
      } 
     } 
    } 
} 

Puede hacer referencia a esto directamente en su etiqueta img:

<img src="GetImage.ashx?id=111"/> 

O, incluso se podría crear un control de servidor que lo hace por usted:

using System; 
using System.Web; 
using System.Web.UI; 
using System.Web.UI.WebControls; 

namespace Example.WebControl 
{ 

    [ToolboxData("<{0}:DatabaseImage runat=server></{0}:DatabaseImage>")] 
    public class DatabaseImage : Control 
    { 

     public int DatabaseId 
     { 
      get 
      { 
       if (ViewState["DatabaseId" + this.ID] == null) 
        return 0; 
       else 
        return ViewState["DataBaseId"]; 
      } 
      set 
      { 
       ViewState["DatabaseId" + this.ID] = value; 
      } 
     } 

     protected override void RenderContents(HtmlTextWriter output) 
     { 
      output.Write("<img src='getImage.ashx?id=" + this.DatabaseId + "'/>"); 
      base.RenderContents(output); 
     } 
    } 
} 

Esto podría usarse como

<cc:DatabaseImage id="db1" DatabaseId="123" runat="server/> 

Y, por supuesto, puede establecer la ID de base de datos en el código de seguimiento según sea necesario.

+0

¿Qué es? imagen/pjpeg? Es un error en IE, no es un tipo de mime válido para ser utilizado en el servidor;) –

0

Agregue el código a un controlador para devolver los bytes de la imagen con el tipo de mime apropiado. Luego puede agregar la url a su controlador como si fuera una imagen. Por ejemplo:

<img src="myhandler.ashx?imageid=5"> 

¿Tiene sentido?

5

No desea publicar blobs desde una base de datos sin implementar el almacenamiento en caché del lado del cliente.

Usted tendrá que manejar los siguientes encabezados para apoyar el almacenamiento en caché del lado del cliente:

  • ETag
  • Expira
  • Last-Modified
  • If-Match
  • If-None-Match
  • If-Modified-Since
  • If-Unmodified-Since
  • A menos-Modified-Since

Para un controlador HTTP que hace esto, echa un vistazo a: http://code.google.com/p/talifun-web/wiki/StaticFileHandler

Tiene un buen ayudante para servir el contenido. Debería ser fácil pasarle el flujo de la base de datos. También almacena el caché del lado del servidor, lo que debería ayudar a aliviar parte de la presión en la base de datos.

Si alguna vez decide servir contenido de transmisión desde la base de datos, pdfs o archivos de gran tamaño, el controlador también admite 206 solicitudes parciales.

También es compatible con compresión gzip y desinflar.

Estos tipos de archivos se beneficiarán de una mayor compresión:

  • CSS, JS, HTM, HTML, SWF, XML, XSLT, txt
  • doc, xls, ppt

Hay algunos tipos de archivos que no se beneficiarán de una mayor compresión:

  • pdf (causa problemas con ciertas versiones en IE y es usu aliado así comprimido)
  • png, jpg, jpeg, gif, ico
  • WAV, MP3, M4A, AAC (wav a menudo se comprime)
  • 3GP, 3G2, ASF, AVI, DV, FLV, MOV, MP4 , mPG, MPEG, WMV
  • zip, rar, 7z, ARJ
+0

¡Guau! ¡Esta pregunta tiene más de un año! Gracias por la respuesta, sin embargo, he resuelto el problema. +1 para la respuesta bien documentada. –

+0

Como alternativa, puede almacenar en caché en el disco y permitir que IIS maneje ETag, Last-Modified, etc. Como [ImageResizing.net] (http://imageresizing.net) sí. IIS tiene una buena ventaja de rendimiento sobre el código administrado para servir archivos estáticos, incluso con una implementación .NET óptima. –

+0

Es por eso que hago mi procesamiento fuera de línea y de una manera escalable. https://github.com/taliesins/talifun-commander – Taliesin

2

el uso de ASP.Net MVC con esto es bastante fácil hacia adelante. Codificar un controlador con un método como este:

public FileContentResult Image(int id) 
{ 
    //Get data from database. The Image BLOB is return like byte[] 
    SomeLogic ItemsDB= new SomeLogic("[ImageId]=" + id.ToString()); 
    FileContentResult MyImage = null; 
    if (ItemsDB.Count > 0) 
    { 
     MyImage= new FileContentResult(ItemsDB.Image, "image/jpg"); 
    } 

    return MyImage; 
} 

En su ASP.NET Web o en este ejemplo, en el formulario Web ASP.NET puede rellenar un control de imagen con la URL de su método como este :

  this.imgExample.ImageUrl = "~/Items/Image/" + MyItem.Id.ToString(); 
      this.imgExample.Height = new Unit(120); 
      this.imgExample.Width = new Unit(120); 

Voilá. No se necesitaba molestia de HttpModules.

Cuestiones relacionadas