MVC Cómo mostrar una imagen de matriz de bytes del modelo

Tengo un modelo con un archivo de imagen de matriz de bytes que quiero mostrar en la página.

¿Cómo puedo hacer eso sin volver a la base de datos?

Todas las soluciones que veo utilizan un ActionResult para volver a la base de datos para recuperar la imagen, pero ya tengo la imagen en el modelo …

Algo como esto puede funcionar …

@{ var base64 = Convert.ToBase64String(Model.ByteArray); var imgSrc = String.Format("data:image/gif;base64,{0}", base64); }  

Como se menciona en los comentarios a continuación, utilice lo anterior armado con el conocimiento de que, aunque esto pueda responder a su pregunta, puede que no resuelva su problema . Dependiendo de su problema, esta puede ser la solución, pero no descartaría por completo el acceso a la base de datos dos veces.

Esto funcionó para mí

  

Recomiendo algo en esta línea, incluso si la imagen vive dentro de su modelo.

Me doy cuenta de que está pidiendo una forma directa de acceder desde la vista y muchos otros respondieron eso y le dijeron qué es lo que está mal con ese enfoque, así que esta es solo otra manera de cargar la imagen de una manera asíncrona para usted y yo creo que es un mejor enfoque.

Modelo de muestra:

 [Bind(Exclude = "ID")] public class Item { [Key] [ScaffoldColumn(false)] public int ID { get; set; } public String Name { get; set; } public byte[] InternalImage { get; set; } //Stored as byte array in the database. } 

Método de muestra en el controlador:

 public async Task RenderImage(int id) { Item item = await db.Items.FindAsync(id); byte[] photoBack = item.InternalImage; return File(photoBack, "image/png"); } 

Ver

 @model YourNameSpace.Models.Item @{ ViewBag.Title = "Details"; } 

Details

Item


@Html.DisplayNameFor(model => model.Name)
@Html.DisplayFor(model => model.Name)

Una forma es agregar esto a una nueva clase c # o clase HtmlExtensions

 public static class HtmlExtensions { public static MvcHtmlString Image(this HtmlHelper html, byte[] image) { var img = String.Format("data:image/jpg;base64,{0}", Convert.ToBase64String(image)); return new MvcHtmlString(""); } } 

entonces puedes hacer esto en cualquier vista

 @Html.Image(Model.ImgBytes) 

Si puede codificar sus bytes en base-64, podría intentar usar el resultado como su fuente de imagen. En su modelo, puede agregar algo como:

 public string ImageSource { get { string mimeType = /* Get mime type somehow (eg "image/png") */; string base64 = Convert.ToBase64String(yourImageBytes); return string.Format("data:{0};base64,{1}", mimeType, base64); } } 

Y en su opinión:

  

Si la imagen no es tan grande, y si hay una buena posibilidad, la volverás a utilizar con frecuencia, y si no tienes demasiados, y si las imágenes no son secretas (lo que significa que no es grande) tratar si un usuario podría ver la imagen de otra persona) …

Hay un montón de “si” aquí, así que hay una buena posibilidad de que esto sea una mala idea:

Puede almacenar los bytes de imágenes en Cache durante un tiempo breve y hacer que una etiqueta de imagen apunte hacia un método de acción, que a su vez lee desde la caché y escupe su imagen. Esto permitirá que el navegador guarde en caché la imagen de manera apropiada.

 // In your original controller action HttpContext.Cache.Add("image-" + model.Id, model.ImageBytes, null, Cache.NoAbsoluteExpiration, TimeSpan.FromMinutes(1), CacheItemPriority.Normal, null); // In your view:  // In your controller: [OutputCache(VaryByParam = "fooId", Duration = 60)] public ActionResult GetImage(int fooId) { // Make sure you check for null as appropriate, re-pull from DB, etc. return File((byte[])HttpContext.Cache["image-" + fooId], "image/gif"); } 

Esto tiene el beneficio adicional (¿o es una muleta?) De trabajar en navegadores más antiguos, donde las imágenes en línea no funcionan en IE7 (o IE8 si es más grande que 32kB).

Esta es una versión modificada de la respuesta de Manoj que uso en un proyecto. Acabo de actualizar para tomar una clase, atributos html y usar TagBuilder.

  public static IHtmlString Image(this HtmlHelper helper, byte[] image, string imgclass, object htmlAttributes = null) { var builder = new TagBuilder("img"); builder.MergeAttribute("class", imgclass); builder.MergeAttributes(new RouteValueDictionary(htmlAttributes)); var imageString = image != null ? Convert.ToBase64String(image) : ""; var img = string.Format("data:image/jpg;base64,{0}", imageString); builder.MergeAttribute("src", img); return MvcHtmlString.Create(builder.ToString(TagRenderMode.SelfClosing)); } 

Que se puede utilizar entonces de la siguiente manera:

  @Html.Image(Model.Image, "img-cls", new { width="200", height="200" }) 

Necesitas tener un byte [] en tu DB.

Mi byte [] está en mi objeto Person:

 public class Person { public byte[] Image { get; set; } } 

Necesita convertir su byte [] en una cadena. Entonces, tengo en mi controlador:

 String img = Convert.ToBase64String(person.Image); 

A continuación, en mi archivo .cshtml, mi modelo es un ViewModel. Esto es lo que tengo en:

  public String Image { get; set; } 

Lo uso así en mi archivo .cshtml:

  

“data: extensión de archivo de imagen / imagen ; base64, {0}, su cadena de imágenes

¡Deseo que ayude a alguien!

Si desea presentar la imagen, agregue un método como una clase auxiliar o al propio modelo y permita que el método convierta la imagen de matriz de bytes a un formato de imagen como PNG o JPG y luego convierta a cadena Base64. Una vez que tenga eso, enlace el valor de base64 en su vista en el formato

“datos: imagen / [extensión de tipo de archivo de imagen] ; base64, [su cadena base64 va aquí]

Lo anterior se asigna al atributo src la etiqueta img .

El único problema que tengo con esto es que la cadena base64 es demasiado larga. Por lo tanto, no lo recomendaría para múltiples modelos que se muestran en una vista.

He creado un método de ayuda basado en lo que sigue a continuación y estoy muy contento de que este ayudante pueda ayudar al mayor número posible.

Con un modelo:

  public class Images { [Key] public int ImagesId { get; set; } [DisplayName("Image")] public Byte[] Pic1 { get; set; } } 

El ayudante es:

 public static IHtmlString GetBytes(this HtmlHelper helper, System.Linq.Expressions.Expression> expression, byte[] array, string Id) { TagBuilder tb = new TagBuilder("img"); tb.MergeAttribute("id", Id); var base64 = Convert.ToBase64String(array); var imgSrc = String.Format("data:image/gif;base64,{0}", base64); tb.MergeAttribute("src", imgSrc); return MvcHtmlString.Create(tb.ToString(TagRenderMode.SelfClosing)); } 

La vista recibe un objeto: ICollection por lo que debe usarlo en la vista en una statement foreach:

  @foreach (var item in Model) @Html.GetBytes(itemP1 => item.Pic1, item.Graphics, "Idtag") }