2009-08-28 48 views
5

Tengo una imagen almacenada en mi base de datos de SQL Server almacenada con mis datos de usuario que recupero todos a la vez.Byte de transmisión [] a Imagen en ASP.NET C#

Ahora tengo el byte [] directamente en la página en la que quiero mostrarlo. ¿Cómo lo pongo en mi WebControls.Image? No quiero tener que llamar a HttpHandler y llamar a la base de datos de nuevo.

Obviamente, simplemente lo envía a toda la página.

  Context.Response.BinaryWrite(user.Picture.ToArray()); 
+0

¿No puede almacenar los datos de imagen como archivo? – AnthonyWJones

+0

Esta fue la primera ruta, pero almacenar la imagen en la base de datos fue la solución preferida. (Por encima de mi cabeza) Así que tengo que sacar lo mejor de la situación. – markoo

+0

Gracias por ayudar a todos. Respuestas rápidas y perspicaces. – markoo

Respuesta

4

Si se trata de una imagen pequeña, la mostrarías como datos codificados en base64 en una etiqueta de imagen. See here for a similar situation.

Pero en el 99.9% de todas las situaciones crearía un HttpHandler que devuelve la imagen. Es la forma más fácil y rápida de hacerlo, creo.

+0

Esto era exactamente lo que estaba buscando. La imagen es un pequeño gif/jpeg de 180 x 160 px. Terminó así: byte [] picByteArray = user.Picture.ToArray(); cadena myPicString = Convert.ToBase64String (picByteArray); myPicture.Attributes ["src"] = "data: image/gif; base64," + myPicString; – markoo

+0

@Markoo: ¿Cuántos bytes termina siendo codificado en base64? Al colocar los datos de la imagen directamente en el código HTML generado dinámicamente, usted requiere que el cliente los busque cada vez, no es almacenable en caché a menos que haga que toda la respuesta html sea almacenable en caché. – AnthonyWJones

+0

Mi imagen termina siendo alrededor de 8 KB, lo que en mi simple vista de datos de usuario es bastante aceptable. Es un sitio de administración "interna" dentro de mi empresa. Aunque el componente real se usará externamente. Los administradores y administradores de estos sitios y componentes externos tienen una gran caché. Así que no tengo preocupaciones en la implementación de esta solución. Estos perfiles son muy limitados. Sólo alrededor de 20 o 30 en casa periodistas. Por lo tanto, parecía excesivo tener una tabla de imágenes separada solo para estos. Gracias de nuevo por su visión. – markoo

0

crear página separada donde se va a crear la imagen, por ejemplo: image.aspx y utilizarlo en otras páginas

<img src="image.aspx?id=number" > 

número es el ID de la imagen en la base de datos

+0

No use ASPX para generar imágenes, use un ashx. – AnthonyWJones

+0

@Anthony: El OP dice que no quieren usar un 'ashx', aunque estoy de acuerdo en que es la manera correcta de hacerlo. (¡Y crear un 'aspx' no es más fácil que crear un' ashx' de todos modos!) – LukeH

+0

@Anthony: No sé la diferencia. Es solo extensión, ¿no? Puede ser incluso number.jpg con enrutamiento. –

1

Wrap la matriz de bytes en un objeto MemoryStream y colocarlo en ASP.NETs Cache.

MemoryStream ms = new MemoryStream(user.Picture.ToArray()); 
Guid imageGuid = new Guid(); 
HttpRuntime.Cache.Add(imageGuid.ToString(), ms, null, 
    DateTime.Now.AddMinutes(5), Cache.NoSlidingExpiration, CacheItemPriority.Normal, null); 

A continuación, utilice un controlador (.ashx) para extraerlo de la caché y enviarlo al cliente.

string imageGuid = context.Request.QueryString[image]; 
MemoryStream ms = (MemoryStream)HttpRuntime.Cache[imageGuid]; 
// configure context.Response with appropriate content type and cache settings 

// ** Edit ** 
// It seems I need to be more explicit with regard to the above comment:- 
context.Response.Cache.SetCacheability(HttpCacheability.Public); 
context.Response.Cache.SetLastModified(DateTime.UtcNow); 
context.Response.Cache.SetExpires(DateTime.UtcNow.AddHours(2); 
context.Response.Cache.SetMaxAge(TimeSpan.FromHours(2)); 
context.Response.Cache.SetValidUntilExpires(true); 

ms.WriteTo(context.Response.OutputStream); 

Ahora puede soltar el MemoryStream del Caché.

HttpRuntime.Cache.Remove(imageGuid); 
+0

Esto no se escalará en una webfarm (a menos que tenga algún tipo de caché distribuida). – LukeH

+0

Nunca hagas esto. Estás sacrificando todas las bondades de HTTP ('If-Modified-Since', caching, etc.) y la escalabilidad para absolutamente ningún beneficio. –

+0

@anton: ¿viste la línea comentada en mi código? ¿Qué piensas que quiero decir con eso? – AnthonyWJones

0

Hace falta un programa IHttpHander que escribir bytes de imagen y adecuada Content-Type a una secuencia de respuesta. Ver this, this y this.

+0

Has perdido el punto en la Pregunta. Dado que tiene en una página ASPX de ejecución una matriz de bytes de datos de imágenes adquiridos desde una base de datos, ¿cómo obtendría un ' AnthonyWJones

+0

@Anthony: Seguramente el punto es que no necesita extraer los datos de imagen de la base de datos en la página. No necesita * volver a consultar * la base de datos, necesita * consultarla una vez * en el lugar/hora apropiado (es decir, en un manejador 'ashx' separado) – LukeH

+0

@Luke: Eso puede ser, pero nosotros No lo sé, ¿verdad? Todo lo que tenemos de la pregunta es que, por alguna razón, tiene un objeto que ya tiene un objeto Picture cargado. Tal vez eso se puede evitar mejor aún colocar la imagen en el sistema de archivos. Prefiero responder la pregunta en cuestión, especialmente dado que algunos otros usuarios de SO pueden encontrar en algún momento que están en esta situación por razones inevitables. – AnthonyWJones

0

Estoy bastante seguro de que no puedes hacer esto en la página.

Si no desea crear un controlador HTTP para generar la imagen, entonces su alternativa es crear una página aspx por separado. Establezca el src de su etiqueta img para apuntar a esa página, pasando algún tipo de ID en la cadena de consulta para que los datos de imagen se puedan extraer de la base de datos.

Habiendo dicho eso, configurar una página aspx para hacer esto no es más rápido o más fácil que configurar un ashx. Recomendaría hacer esto right forma y crear un controlador HTTP.

+0

Ya tengo los datos de la base de datos. Quiero guardar otra llamada. – markoo