MVC Come visualizzare un’immagine di array di byte dal modello

Ho un modello con un file immagine array di byte che voglio mostrare sulla pagina.

Come posso farlo senza tornare al Database?

Tutte le soluzioni che vedo utilizzano un ActionResult per tornare al database per recuperare l’immagine, ma ho già l’immagine sul modello …

Qualcosa del genere potrebbe funzionare …

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

Come menzionato nei commenti qui sotto, si prega di utilizzare quanto sopra armati con la consapevolezza che, sebbene questo possa rispondere alla tua domanda, potrebbe non risolvere il tuo problema . A seconda del problema, questa potrebbe essere la soluzione, ma non escluderei completamente l’accesso al database due volte.

Questo ha funzionato per me

  

Raccomando qualcosa in questo senso, anche se l’immagine vive all’interno del tuo modello.

Mi rendo conto che stai chiedendo un modo diretto per accedervi dal punto di vista e molti altri hanno risposto e ti hanno detto cosa c’è di sbagliato in questo approccio, quindi questo è solo un altro modo per caricare l’immagine in modo asincrono per te e per te pensare è un approccio migliore.

Modello di esempio:

 [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. } 

Metodo di esempio nel controller:

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

vista

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

Details

Item


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

Un modo è quello di aggiungere questo a una nuova class c # o class 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(""); } } 

allora puoi farlo in qualsiasi vista

 @Html.Image(Model.ImgBytes) 

Se è ansible codificare i byte in base 64, è ansible provare a utilizzare il risultato come origine dell’immagine. Nel tuo modello potresti aggiungere qualcosa come:

 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); } } 

E a tuo avviso:

  

Se l’immagine non è così grande, e se ci sono buone possibilità di riutilizzare l’immagine spesso, e se non ne hai troppe, e se le immagini non sono segrete (significa che non è grande trattare se un utente potrebbe potenzialmente vedere l’immagine di un’altra persona) …

Un sacco di “se” è qui, quindi c’è una buona possibilità questa è una ctriggers idea:

È ansible memorizzare i byte immagine in Cache per un breve periodo e creare un tag immagine puntato su un metodo di azione, che a sua volta legge dalla cache e sputa l’immagine. Ciò consentirà al browser di memorizzare l’immagine in modo appropriato.

 // 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"); } 

Questo ha l’ulteriore vantaggio (o è una stampella?) Di lavorare con i browser più vecchi, dove le immagini in linea non funzionano in IE7 (o IE8 se maggiore di 32kB).

Questa è una versione modificata della risposta di Manoj che uso su un progetto. Appena aggiornato per prendere una class, attributi html e usare il 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)); } 

Quale può essere usato allora come segue:

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

Devi avere un byte [] nel tuo DB.

Il mio byte [] è nell’object Person:

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

Devi convertire il tuo byte [] in una stringa. Quindi, ho nel mio controller:

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

Successivamente, nel mio file .cshtml, il mio modello è un ViewModel. Questo è quello che ho in:

  public String Image { get; set; } 

Lo uso in questo modo nel mio file .cshtml:

  

“dati: estensione file immagine / immagine ; base64, {0}, stringa immagine

Vorrei che potesse aiutare qualcuno!

Se si desidera presentare l’immagine, aggiungere un metodo come class helper o al modello stesso e consentire al metodo di convertire l’immagine dell’array di byte in un formato immagine come PNG o JPG, quindi convertire in stringa Base64. Una volta ottenuto ciò, associa il valore base64 alla vista nel formato

“data: image / [estensione del file di immagine] ; base64, [la stringa base64 va qui]

Quanto sopra è assegnato all’attributo src del tag img .

L’unico problema che ho con questo è che la stringa base64 è troppo lunga. Quindi, non lo consiglierei per i modelli multipli mostrati in una vista.

Ho creato un metodo di supporto basato sull’asnwer qui sotto e sono abbastanza contento che questo helper possa aiutarti il ​​più ansible.

Con un modello:

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

L’aiutante è:

 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 sta ricevendo un object: ICollection quindi è necessario utilizzarlo nella vista in un’istruzione foreach:

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